项目
项目是具有明确目标和完成状态的工作——与 Areas(持续责任)不同。一个项目是知识库中的一个文件夹,与任务后端中的一个项目配对:文件夹保存项目的含义,后端保存其任务(tasks.md)。每个任务调用都是对 tasks.md 的操作,根据 TASKS 的适配器运行。
基础层
在行动之前,请读取:相对于此技能基础目录的 ../../para/<file>.md——这些文件包含共享规则,不要凭记忆复述:
../../para/paths.md— 始终,包括“语言”:下面的字符串来自lang/<LANG>.md../../para/tasks.md— 始终:操作、配对、什么是任务../../para/find-target.md— 用于overview和task../../para/note-format.md— 用于create;对于每个子命令,“旧字段”../../para/project-id.md— 用于create../../para/dod.md— 用于create(编写project.dod部分)和overview../../para/thresholds.md— 用于list和overview:项目排序、过期、时间范围、任务计数、输出大小../../para/confirm.md—create和task写入(1 级);list和overview不写入../../para/move.md— 用于create,在写入可能冲突的文件夹之前
子命令
$ARGUMENTS 的第一个单词选择子命令:list、create、overview、task。如果都不是,则根据措辞推断出意图并告知你选择了哪一个。空的 $ARGUMENTS → 运行 list,然后询问要做什么。
每个子命令都会遇到早于任务后端的项目:status、Tasks/(note-format.md 说明何时该字段被视为旧的)、没有 tasks_ref 字段。按照 note-format.md “旧字段”所述读取它们——报告,绝不重写。
create <description> — 启动一个项目
输入:项目是什么、其目标、截止日期、第一步。为空 → 询问项目是什么以及其目标。
-
从磁盘读取
Templates/Project.md,逐字读取。 -
根据
note-format.md推导出标题。它有三种用途:作为title和 H1(不带 ID 前缀),以及——带前缀——作为文件夹名称和概述文件名。按照note-format.md提议short。 -
根据
project-id.md发布 ID。 -
在
Projects/下创建文件夹结构:PROJ-xxxx <title>/ ├── PROJ-xxxx <title>.md ← 概述,来自 Templates/Project.md ├── Notes/ ├── Resources/ └── Results/所有三个子文件夹,即使为空。没有
Tasks/(当TASKS = files时,适配器会在添加第一个任务时创建它)。 -
按照
note-format.md中的项目行填充前置元数据。created是今天。deadline仅在描述中给出时填写。tasks_ref保持空白直到步骤 7(当pairing: none时,该字段被省略)。 -
填充正文:
project.goal部分 — 目标/期望的最终状态。必填。project.value部分 — 用户获得的收益,可衡量或明确(note-format.md,“关于结果的三个部分”)。必填。 如果此部分或project.goal从输入中不清楚,在写入前在一个问题中询问两者(confirm.md,1.5 级)。project.problem部分 — 启动项目的原因。project.expected_result部分 — 具体的产出物及其存放位置。project.scope部分 — 仅包含用户命名的项目。通常为空:研究任务会填充它(tasks.md“研究任务”)。project.dod部分 — 根据dod.md的复选框。如果描述不允许你推导出实际的勾选项,则询问——就像缺少project.goal一样。common.links部分 — 指向明确相关笔记的 Wiki 链接,否则使用模板的-。
-
根据
tasks.md“配对”创建配对:project.create,使用标题和 ID。当pairing: separate时,将返回的ref写入tasks_ref:;如果调用失败,则说明:文件夹保持未配对状态,并且/projects task稍后会提供配对的选项。当pairing: none时,没有配对且没有tasks_ref:跳过写入。 -
新项目中的第一个任务,不带日期:
- 研究任务,根据
tasks.md“研究任务”,始终执行,除非用户已经命名了完整范围——则将其写入project.scope部分代替; - 用户明确命名的步骤,使用
task.add添加,并根据“什么是任务”措辞。不能措辞为行动的步骤是研究的问题,而不是任务。
绝不发明用户没有命名的步骤。
- 研究任务,根据
-
报告文件夹路径、ID、标题、
short(提供更改选项)、截止日期、目标、价值行、后端项目名称以及创建的任务。
如果输入描述的是没有终点的持续责任,那么这不是一个项目——说明并提供 /areas create 代替。如果这是一个用户尚未决定承担的想法,说明这还不是一个项目(tasks.md “配对”),并提供将其保留在收件箱中(inbox.name)。
task <project> <task> — 添加任务
- 根据
find-target.md找到项目,操作为“向项目添加任务”。目标也可能是来自areas.md中AREA_TASK_PROJECTS的区域项目——通过名称匹配。 - 解析去向:区域项目 →
area;否则,概述的tasks_ref→project_ref(当pairing: none时,项目文件夹是ref,这一步就是项目本身)。pairing: separate且概述上没有tasks_ref→ 说出task.unpaired字符串并提供创建它的选项(create的步骤 7)。如果同意,则创建配对,然后继续。绝不将任务写入知识库中。
- 根据
tasks.md“什么是任务”措辞任务。如果用户的措辞已经合适,则保留;否则在公告中提出重新措辞后的版本。如果它不能成为行动,则询问下一步(1.5 级)。 task.add,使用project_ref或area(当TASKS = files时,已占用的基本名称是冲突:note-format.md“名称冲突”,询问,不静默添加后缀):文本、更长内容的描述、仅当给出时的duration。日期规则是tasks.md“字段”。- 报告任务和项目。
overview <project> — 项目状态
只读。 不写入任何内容——既不写入知识库,也不写入后端。如果摘要揭示了值得修复的内容,请说明并让用户决定。
-
根据
find-target.md找到项目,操作为“报告”。没有参数时,列出项目并询问。 -
阅读概述笔记:前置元数据和
project.goal、project.value、project.expected_result、project.dod、common.links部分。空白字段报告为空白,绝不通过推断填充。 -
读取任务(
task.list,打开):它们的日期和持续时间。根据thresholds.md“任务计数”计算计数。当pairing: separate时,没有配对 → 跳过,并说出task.unpaired字符串。 -
完整阅读
Notes/(以及Results/,如果其中有内容),直到thresholds.md中的上限——这是决策和风险实际所在之处。 -
旧格式。 如果概述带有
status/priority/value/estimate,或者文件夹有一个旧的Tasks/(note-format.md),添加一行,overview.legacy字符串,包含{fields}如status, Tasks/ (3 files)(文件夹计数是overview.legacy_tasks字符串),仅命名存在的内容。不读取任务笔记以获取进度;迁移决定什么保留。 -
信号 — 仅报告触发的信号:
- 项目的
deadline已过,或在thresholds.md的时间范围内; - 逾期的任务 — 说明逾期了多少天;
- 截止日期在时间范围内但没有任何计划;
- 有日期但没有持续时间的任务;
- 安静时间长于
thresholds.md中的项目阈值,按照其说明测量(配对时为project.activity,否则为 mtime,根据thresholds.md); common.links部分中的孤立 Wiki 链接;- 所有验收标准都已勾选但项目仍在
Projects/中 — 已完成但未关闭。
- 项目的
-
以
LANG渲染到聊天。 标签是lang/<LANG>.md字符串,在下面的模板中通过大括号中的键命名;此处显示为英文:## PROJ-0001 · Project A **{overview.area}** Area A · **{overview.deadline}** 2026-10-31 — 14 days **{overview.tasks}** {count.scheduled} 3 · {count.overdue} 1 · {count.backlog} 6 **{overview.acceptance}** ☑☐☐ 1/3 ### {overview.essence} <The goal, 1–2 sentences.> <The expected result — one line.> <The value — one line.> ### {overview.scheduled} - **Write the supplier an email** — Tue 10-21, 30 min - **Fill in the form** — overdue by 2 days, 1 h ### {overview.backlog} - Book an appointment - …and 3 more ### {overview.digest} - <A key decision or conclusion from Notes/ — in your own words.> ### {overview.signals} - Deadline in 14 days, nothing scheduled大括号是键,不是文字:打印每个键代表的字符串。日期使用
common.date格式(2026-10-31;短格式common.date_short为10-31,任务行中与来自common.weekdays的星期几一起使用);到截止日期的天数是common.days;单位缩写是common.unit.*;逾期任务携带task.overdue_by字符串;积压尾部是overview.backlog_more字符串({n}= 未显示的任务)。overview.backlog部分显示最旧的未注明日期的任务,直到thresholds.md中的上限。删除任何会空的节或字段。空的Results/是正常状态。
list — 项目列表
只读。 每个项目一行——索引,而不是摘要:绝不打开 Notes/。
-
枚举
Projects/下直接存在的文件夹。已归档的项目不列出——那是/archive list做的事。 -
读取概述前置元数据:
id、title、area、deadline,以及当pairing: separate时的tasks_ref。没有前置元数据的文件夹是约定前——以文件夹名称打印,并附上common.no_metadata字符串。 -
读取每个有
ref的项目的任务(task.list,使用project_ref,打开),根据thresholds.md“任务计数”计数。 -
根据
thresholds.md“项目顺序”排序。 -
以
LANG渲染,使用list.*、count.*和task.unpaired字符串——行紧凑,因此积压计数是count.backlog_short(表头list.header,截止日期list.until日期使用common.date_short,并且在thresholds.md的时间范围内,后面加上(14 d):剩余天数和common.unit.day);此处显示为英文:**Projects (4)** 1. PROJ-0008 Project A — Area A · until 10-31 (14 d) · scheduled 2 · backlog 3 2. PROJ-0020 Project B — until 10-31 (14 d) · scheduled 0 · backlog 3 3. PROJ-0009 Project C — Area B · until 02-28 · no pair in the task manager · old format 4. PROJ-0027 Project D — backlog empty No pair in the vault: «Project E»- 已过的截止日期:
list.deadline_passed字符串。 - 存在旧字段或旧的
Tasks/时:list.legacy字符串。 - 积压为空的项目:
list.backlog_empty字符串。 - 最后一行(
list.orphans)命名没有概述指向的后端项目,通过tasks.md“表格注释”、project.list找到。当为空或适配器不支持project.list时,删除此行。 - 删除任何空白字段,而不是打印占位符。空的
Projects/是一个有效答案:直接说明。
- 已过的截止日期:
已归档和约定前的项目
Archive/ 中的项目可能早于约定:没有前置元数据、没有 PROJ-xxxx 前缀、没有子文件夹。从笔记中读取 project.goal 部分,跳过任务部分和 overview.acceptance,并直接说明它已归档且采用旧格式。
备注
- 计算,不要估算:天数、任务计数和逾期时间来自后端、文件和今天的系统日期。如果某个字段为空而无法计算,则说明它为空而不是猜测。
- 总结报告状态,不评判用户。说“逾期 5 天”,而不是“你放弃了项目”。
- 所有内容(包括任务)都以
LANG显示。