@njeybe/nativ 2.5.1 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +67 -0
- package/README.md +100 -5
- package/dist/commands/design-check.d.ts +4 -0
- package/dist/commands/design-check.js +76 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +55 -11
- package/dist/commands/notify.d.ts +2 -0
- package/dist/commands/notify.js +25 -0
- package/dist/commands/session.d.ts +22 -0
- package/dist/commands/session.js +106 -0
- package/dist/commands/task/task-add.js +1 -1
- package/dist/commands/task/task-common.js +6 -6
- package/dist/commands/task/task-escalate.js +8 -10
- package/dist/commands/task/task-lifecycle.d.ts +7 -1
- package/dist/commands/task/task-lifecycle.js +30 -5
- package/dist/commands/task/task-query.d.ts +2 -0
- package/dist/commands/task/task-query.js +27 -12
- package/dist/commands/task/task-reclaim.d.ts +20 -0
- package/dist/commands/task/task-reclaim.js +87 -0
- package/dist/commands/task.d.ts +2 -0
- package/dist/commands/task.js +1 -0
- package/dist/commands/triage.js +3 -3
- package/dist/commands/update.js +46 -0
- package/dist/commands/validate.js +1 -0
- package/dist/commands/verify.js +21 -5
- package/dist/core/design-rules.d.ts +23 -0
- package/dist/core/design-rules.js +115 -0
- package/dist/core/enforcement.js +18 -17
- package/dist/core/harness-integrity.js +26 -7
- package/dist/core/lock-manager.d.ts +6 -0
- package/dist/core/lock-manager.js +50 -41
- package/dist/core/notify.d.ts +38 -0
- package/dist/core/notify.js +133 -0
- package/dist/core/profiles.js +7 -16
- package/dist/core/session-memory.d.ts +42 -0
- package/dist/core/session-memory.js +121 -0
- package/dist/core/setup/pm-playbook.d.ts +5 -0
- package/dist/core/setup/pm-playbook.js +26 -0
- package/dist/core/setup/session-context.js +35 -2
- package/dist/core/setup/setup-planner.js +2 -2
- package/dist/core/setup/types.d.ts +2 -0
- package/dist/core/setup/types.js +5 -1
- package/dist/core/task-claims.d.ts +15 -0
- package/dist/core/task-claims.js +32 -0
- package/dist/core/tier1-liaison.d.ts +1 -0
- package/dist/core/tier1-liaison.js +25 -27
- package/dist/core/verifier/output-digest.d.ts +19 -0
- package/dist/core/verifier/output-digest.js +48 -0
- package/dist/db/data-engine.js +33 -32
- package/dist/db/introspector.js +61 -60
- package/dist/db/sqlite.d.ts +3 -0
- package/dist/db/sqlite.js +10 -0
- package/dist/governor/circuit-breaker.js +12 -0
- package/dist/governor/patch-applier.d.ts +1 -0
- package/dist/governor/patch-applier.js +3 -7
- package/dist/index.js +40 -6
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +53 -14
- package/dist/providers/claude-api.js +3 -0
- package/dist/providers/gemini.js +4 -1
- package/dist/providers/registry.d.ts +6 -2
- package/dist/providers/registry.js +28 -16
- package/dist/providers/types.d.ts +4 -1
- package/dist/runner/agent-supervisor.js +2 -2
- package/dist/runner/cli-config.js +1 -1
- package/dist/scanner/types.d.ts +5 -1
- package/dist/scanner/types.js +7 -0
- package/dist/server/routes/task-routes.d.ts +2 -0
- package/dist/server/routes/triage-routes.js +3 -18
- package/dist/server/studio-ui/pages/benchmarks/styles.js +8 -5
- package/dist/server/studio-ui/pages/database/browser.js +1 -1
- package/dist/server/studio-ui/pages/database/connection.js +1 -1
- package/dist/server/studio-ui/pages/database/data-shell.js +5 -5
- package/dist/server/studio-ui/pages/database/drift.js +1 -1
- package/dist/server/studio-ui/pages/database/explorer.js +2 -2
- package/dist/server/studio-ui/pages/database/styles.js +5 -5
- package/dist/server/studio-ui/pages/flow/styles.js +3 -3
- package/dist/server/studio-ui/pages/home/script.js +110 -91
- package/dist/server/studio-ui/pages/home/styles.js +33 -45
- package/dist/server/studio-ui/pages/tasks/script.js +150 -3
- package/dist/server/studio-ui/pages/tasks/styles.js +63 -6
- package/dist/server/studio-ui/pages/team/script.js +49 -52
- package/dist/server/studio-ui/pages/team/styles.js +21 -20
- package/dist/server/studio-ui/pages/worktrees/script.js +47 -35
- package/dist/server/studio-ui/pages/worktrees/styles.js +12 -10
- package/dist/server/studio-ui/shell/brand.d.ts +4 -0
- package/dist/server/studio-ui/shell/brand.js +16 -0
- package/dist/server/studio-ui/shell/console.js +61 -2
- package/dist/server/studio-ui/shell/core.js +8 -8
- package/dist/server/studio-ui/shell/detail-view.js +1 -1
- package/dist/server/studio-ui/shell/dispatch.js +18 -0
- package/dist/server/studio-ui/shell/events-tools.js +5 -1
- package/dist/server/studio-ui/shell/format.js +5 -6
- package/dist/server/studio-ui/shell/icons.js +23 -15
- package/dist/server/studio-ui/shell/markup-head.js +11 -6
- package/dist/server/studio-ui/shell/markup-tools.js +19 -10
- package/dist/server/studio-ui/shell/paint.js +3 -0
- package/dist/server/studio-ui/shell/pipeline-state.js +1 -1
- package/dist/server/studio-ui/shell/proposals.js +6 -2
- package/dist/server/studio-ui/shell/pulse.d.ts +1 -0
- package/dist/server/studio-ui/shell/pulse.js +67 -0
- package/dist/server/studio-ui/shell/router.js +25 -0
- package/dist/server/studio-ui/shell/sidebar-view.js +6 -3
- package/dist/server/studio-ui/shell/toasts-format.js +4 -4
- package/dist/server/studio-ui/styles/console.js +33 -13
- package/dist/server/studio-ui/styles/dialogs.js +4 -4
- package/dist/server/studio-ui/styles/responsive.js +8 -0
- package/dist/server/studio-ui/styles/shell.js +24 -5
- package/dist/server/studio-ui/styles/strategist.js +10 -10
- package/dist/server/studio-ui/styles/tokens-base.js +23 -23
- package/dist/server/studio-ui.js +2 -0
- package/package.json +2 -2
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/agents/architect.md +11 -12
- package/plugin/agents/explorer.md +1 -1
- package/plugin/agents/verifier.md +2 -2
- package/plugin/agents/worker.md +5 -7
- package/plugin/skills/nativ/SKILL.md +36 -49
- package/templates/AGENTS.md +36 -49
- package/templates/CLAUDE.md +1 -41
- package/templates/GEMINI.md +3 -2
- package/templates/claude-agents/architect.md +11 -12
- package/templates/claude-agents/explorer.md +1 -1
- package/templates/claude-agents/verifier.md +2 -2
- package/templates/claude-agents/worker.md +5 -7
- package/templates/design/taste/LICENSE +21 -0
- package/templates/design/taste/SOURCE.md +28 -0
- package/templates/design/taste/v1/DIGEST.md +57 -0
- package/templates/design/taste/v1/SKILL.md +226 -0
- package/templates/design/taste/v2/DIGEST.md +62 -0
- package/templates/design/taste/v2/SKILL.md +1206 -0
- package/templates/dot-ai/api_contracts.json +66 -66
- package/templates/dot-ai/context.md +38 -38
- package/templates/dot-ai/db_schema.json +39 -39
- package/templates/dot-ai/subagents/architect.md +6 -0
- package/templates/dot-ai/subagents/flutter-developer.md +2 -11
- package/templates/dot-ai/subagents/frontend.md +47 -44
- package/templates/dot-ai/ui_specs.md +15 -36
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export const dialogsCss = String.raw `/* Toasts */
|
|
3
3
|
/* Bottom-right so notifications never cover the sticky header and navigation. */
|
|
4
4
|
.toast-host { position: fixed; right: 16px; bottom: 16px; z-index: 100; display: flex; flex-direction: column; gap: 8px; width: min(440px, calc(100vw - 32px)); pointer-events: none; }
|
|
5
|
-
.toast { pointer-events: auto; display: flex; gap: 10px; align-items: flex-start; padding: 12px 14px; font-size: 13.5px; background: var(--surface); border: 1px solid var(--
|
|
5
|
+
.toast { pointer-events: auto; display: flex; gap: 10px; align-items: flex-start; padding: 12px 14px; font-size: 13.5px; background: var(--surface); border: 1px solid var(--line-2); border-left: 3px solid var(--danger); border-radius: var(--r-card); box-shadow: var(--shadow); animation: toast-in .18s ease-out; }
|
|
6
6
|
.toast.ok { border-left-color: var(--success); }
|
|
7
7
|
.toast .t-body { flex: 1; min-width: 0; overflow-wrap: anywhere; }
|
|
8
8
|
.toast .t-hint { color: var(--muted); font-size: 12.5px; }
|
|
@@ -12,8 +12,8 @@ export const dialogsCss = String.raw `/* Toasts */
|
|
|
12
12
|
/* Dialogs */
|
|
13
13
|
dialog { border: none; padding: 0; background: transparent; color: var(--text); width: min(640px, calc(100vw - 32px)); max-height: calc(100vh - 32px); }
|
|
14
14
|
dialog.narrow { width: min(460px, calc(100vw - 32px)); }
|
|
15
|
-
dialog::backdrop { background:
|
|
16
|
-
.modal { padding: 22px; background: var(--surface); border: 1px solid var(--
|
|
15
|
+
dialog::backdrop { background: color-mix(in srgb, var(--text) 40%, transparent); backdrop-filter: blur(2px); }
|
|
16
|
+
.modal { padding: 22px; background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-card); box-shadow: var(--shadow); }
|
|
17
17
|
.modal h2 { margin: 0 0 4px; font-size: 18px; font-weight: 600; }
|
|
18
18
|
.modal .lead { color: var(--muted); margin: 0 0 16px; font-size: 14px; line-height: 1.55; }
|
|
19
19
|
.field { margin-bottom: 16px; }
|
|
@@ -112,7 +112,7 @@ textarea.cmd-preview { min-height: 92px; font-family: var(--mono); font-size: 12
|
|
|
112
112
|
.switch-text { display: flex; flex-direction: column; font-size: 13.5px; }
|
|
113
113
|
.switch-text b { font-weight: 600; }
|
|
114
114
|
.switch-text span { font-size: 12.5px; color: var(--muted); }
|
|
115
|
-
kbd { padding: 0 5px; font-family: var(--mono); font-size: 11px; color: var(--muted); background: var(--chip); border: 1px solid var(--chip-border); border-radius:
|
|
115
|
+
kbd { padding: 0 5px; font-family: var(--mono); font-size: 11px; color: var(--muted); background: var(--chip); border: 1px solid var(--chip-border); border-radius: var(--r-control); }
|
|
116
116
|
.btn.primary kbd { color: var(--accent-fg); background: transparent; border-color: color-mix(in srgb, var(--accent-fg) 45%, transparent); }
|
|
117
117
|
|
|
118
118
|
`;
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
// Responsive rules for the kept pages and dialogs.
|
|
2
2
|
export const responsiveCss = String.raw `/* Responsive */
|
|
3
|
+
@media (max-width: 1023px) and (min-width: 761px) {
|
|
4
|
+
:root { --sidebar-w: 56px; }
|
|
5
|
+
.side { padding: 16px 8px; align-items: center; }
|
|
6
|
+
.brand { padding: 0; justify-content: center; }
|
|
7
|
+
.brand .wordmark { height: 16px; width: 16px; overflow: hidden; }
|
|
8
|
+
.brand b, .brand .ver, .nav-glabel, .nav-text, .nav-badge, .side-foot { display: none; }
|
|
9
|
+
.nav-item { justify-content: center; padding: 6px; width: 40px; }
|
|
10
|
+
}
|
|
3
11
|
@media (max-width: 900px) {
|
|
4
12
|
#runner-console-drawer { inset: auto 0 0 0; }
|
|
5
13
|
.panes { grid-template-columns: 1fr; }
|
|
@@ -3,16 +3,17 @@ export const shellCss = String.raw `/* Layout */
|
|
|
3
3
|
.app { display: grid; grid-template-columns: var(--sidebar-w) minmax(0, 1fr); min-height: 100vh; }
|
|
4
4
|
.side { border-right: 1px solid var(--line); background: var(--surface); padding: 16px 12px; display: flex; flex-direction: column; gap: 20px; position: sticky; top: 0; height: 100vh; overflow-y: auto; }
|
|
5
5
|
.brand { display: flex; align-items: center; gap: 10px; padding: 0 6px; }
|
|
6
|
-
.
|
|
6
|
+
.wordmark { height: 18px; width: auto; color: var(--fg); display: block; flex: none; }
|
|
7
|
+
.wordmark.is-rail { height: 16px; }
|
|
7
8
|
.brand b { font-weight: 600; white-space: nowrap; }
|
|
8
|
-
.
|
|
9
|
+
.side-foot .ver { font: 11px var(--mono); color: var(--fg-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
9
10
|
.nav { display: flex; flex-direction: column; gap: 14px; }
|
|
10
11
|
.nav-group { display: flex; flex-direction: column; gap: 2px; }
|
|
11
12
|
.nav-glabel { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--fg-3); padding: 0 8px 4px; }
|
|
12
13
|
.nav-item { display: flex; align-items: center; gap: 10px; min-height: 32px; padding: 7px 8px; border-radius: 7px; border: 0; background: none; text-align: left; color: var(--fg-2); width: 100%; cursor: pointer; transition: background .15s, color .15s; }
|
|
13
|
-
.nav-item svg { width:
|
|
14
|
+
.nav-item svg { width: 20px; height: 20px; flex: none; }
|
|
14
15
|
.nav-item:hover { background: var(--surface-2); color: var(--fg); }
|
|
15
|
-
.nav-item[aria-current="page"] { background: var(--accent-soft); color: var(--
|
|
16
|
+
.nav-item[aria-current="page"] { background: var(--accent-soft); color: var(--fg); font-weight: 600; }
|
|
16
17
|
.nav-badge { margin-left: auto; font: 500 11px var(--font); font-variant-numeric: tabular-nums; min-width: 20px; padding: 1px 6px; border-radius: 999px; background: var(--surface-2); color: var(--fg-2); text-align: center; }
|
|
17
18
|
.nav-badge.warn { background: var(--warn-soft); color: var(--warn); }
|
|
18
19
|
.nav-badge.run { background: var(--run-soft); color: var(--run); }
|
|
@@ -27,6 +28,24 @@ export const shellCss = String.raw `/* Layout */
|
|
|
27
28
|
.top-right { margin-left: auto; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
|
|
28
29
|
.btn.ghost { background: none; border-color: transparent; color: var(--fg-2); box-shadow: none; }
|
|
29
30
|
.btn.ghost:hover { background: var(--surface-2); }
|
|
31
|
+
#btn-dispatch-next[disabled] { opacity: .55; cursor: not-allowed; }
|
|
32
|
+
.spacer { flex: 1; }
|
|
33
|
+
.ic-sun, .ic-moon { display: inline-flex; }
|
|
34
|
+
.ic-moon { display: none; }
|
|
35
|
+
:root[data-theme="light"] .ic-sun { display: none; }
|
|
36
|
+
:root[data-theme="light"] .ic-moon { display: inline-flex; }
|
|
37
|
+
@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) .ic-sun { display: none; } :root:not([data-theme="dark"]) .ic-moon { display: inline-flex; } }
|
|
38
|
+
.pulse-strip { min-height: 32px; height: auto; width: auto; border-radius: 0; background: none; box-shadow: none; animation: none; display: flex; flex-wrap: wrap; align-items: center; gap: 0 20px; padding: 0 24px; border-bottom: 1px solid var(--line); font: 12.5px var(--mono); color: var(--fg-2); }
|
|
39
|
+
#pulse .num { font-variant-numeric: tabular-nums; }
|
|
40
|
+
#pulse .pulse-ms { color: var(--fg); padding-right: 20px; border-right: 1px solid var(--line); }
|
|
41
|
+
#pulse .pulse-item { display: inline-flex; align-items: center; gap: 6px; min-height: 32px; padding: 0; border: 0; background: none; font: inherit; cursor: pointer; }
|
|
42
|
+
#pulse .pulse-item.zero, #pulse .pulse-note.loading { color: var(--fg-3); }
|
|
43
|
+
#pulse .pulse-item.run { color: var(--run); } #pulse .pulse-item.bad { color: var(--bad); } #pulse .pulse-item.warn, #pulse .pulse-note.offline { color: var(--warn); }
|
|
44
|
+
#pulse .pdot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
|
|
45
|
+
#pulse .pulse-item.run .pdot { animation: blink 1.6s infinite; }
|
|
46
|
+
@media (max-width: 1023px) { .pulse-strip { padding-top: 4px; padding-bottom: 4px; gap: 0 16px; } #pulse .pulse-ms { flex-basis: 100%; border-right: 0; padding-right: 0; } }
|
|
47
|
+
.wordmark.is-rail { display: none; }
|
|
48
|
+
@media (max-width: 1023px) { .wordmark { display: none; } .wordmark.is-rail { display: block; } }
|
|
30
49
|
.btn svg { width: 14px; height: 14px; }
|
|
31
50
|
.kbd { font: 11px var(--mono); padding: 0 5px; border: 1px solid var(--line); border-radius: 4px; color: var(--fg-3); }
|
|
32
51
|
.live { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--fg-2); }
|
|
@@ -113,5 +132,5 @@ export const shellCss = String.raw `/* Layout */
|
|
|
113
132
|
.drawer { width: 100%; }
|
|
114
133
|
#runner-console-drawer { inset: auto 0 0 0; }
|
|
115
134
|
}
|
|
116
|
-
@media (prefers-reduced-motion: reduce) { .pulse, .live-dot.flash { animation: none; } * { transition: none !important; } }
|
|
135
|
+
@media (prefers-reduced-motion: reduce) { .pulse, .live-dot.flash, #pulse .pdot { animation: none !important; } * { transition: none !important; } }
|
|
117
136
|
`;
|
|
@@ -12,30 +12,30 @@ export const strategistCss = String.raw `/* Tier 1 AI Strategist (ui_specs.md §
|
|
|
12
12
|
.t1-chip-label { color: var(--muted); }
|
|
13
13
|
.t1-caret { color: var(--muted); transition: transform .15s; }
|
|
14
14
|
.t1-chip[aria-expanded="true"] .t1-caret { transform: rotate(180deg); }
|
|
15
|
-
.t1-menu { position: absolute; top: calc(100% + 6px); right: 0; z-index: 30; width: 300px; padding: 12px; font-size: 12.5px; background: var(--surface); border: 1px solid var(--
|
|
15
|
+
.t1-menu { position: absolute; top: calc(100% + 6px); right: 0; z-index: 30; width: 300px; padding: 12px; font-size: 12.5px; background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-card); box-shadow: var(--shadow); }
|
|
16
16
|
.t1-menu:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
|
|
17
17
|
.t1-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 28px; color: var(--muted); }
|
|
18
18
|
.t1-row b, .t1-row code { color: var(--text); font-weight: 500; font-variant-numeric: tabular-nums; }
|
|
19
19
|
.t1-row code { font-family: var(--mono); font-size: 12px; }
|
|
20
|
-
.t1-switch { position: relative; width: 54px; height: 24px; padding: 0 8px; font: 600 10.5px/22px var(--mono); color: var(--muted); text-align: right; background: var(--chip); border: 1px solid var(--chip-border); border-radius:
|
|
20
|
+
.t1-switch { position: relative; width: 54px; height: 24px; padding: 0 8px; font: 600 10.5px/22px var(--mono); color: var(--muted); text-align: right; background: var(--chip); border: 1px solid var(--chip-border); border-radius: var(--r-control); cursor: pointer; transition: background .15s, border-color .15s; }
|
|
21
21
|
.t1-switch::before { content: ""; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%; background: var(--surface); box-shadow: var(--shadow); transition: transform .15s; }
|
|
22
|
-
.t1-switch[aria-checked="true"] { color:
|
|
22
|
+
.t1-switch[aria-checked="true"] { color: var(--accent-fg); text-align: left; background: var(--success); border-color: var(--success); }
|
|
23
23
|
.t1-switch[aria-checked="true"]::before { transform: translateX(30px); }
|
|
24
24
|
.t1-switch:disabled { opacity: .5; cursor: not-allowed; }
|
|
25
25
|
.t1-policy { display: flex; gap: 6px; margin: 8px 0; padding: 8px; line-height: 1.45; color: var(--muted); background: var(--bg); border: 1px solid var(--border); border-radius: var(--r-control); }
|
|
26
26
|
.t1-policy .icon { flex: none; margin-top: 1px; color: var(--success); }
|
|
27
27
|
.t1-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; margin: 0; }
|
|
28
|
-
.t1-stats div { min-width: 0; padding: 6px 8px; border: 1px solid var(--
|
|
28
|
+
.t1-stats div { min-width: 0; padding: 6px 8px; border: 0; border-left: 1px solid var(--line); border-radius: 0; font-variant-numeric: tabular-nums; }
|
|
29
29
|
.t1-stats dt { font-size: 11px; color: var(--muted); }
|
|
30
30
|
.t1-stats dd { margin: 2px 0 0; font: 600 15px/1.2 var(--mono); font-variant-numeric: tabular-nums; color: var(--text); }
|
|
31
31
|
.t1-strip { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin: 0 0 10px; padding: 8px 10px; color: var(--term-muted); border: 1px solid var(--term-line); border-radius: var(--r-control); }
|
|
32
32
|
.t1-strip > span { display: inline-flex; align-items: center; gap: 6px; }
|
|
33
33
|
.t1-strip strong { color: var(--term-text); font-weight: 600; }
|
|
34
34
|
.t1-strip.is-triaging { border-color: color-mix(in srgb, var(--active) 60%, transparent); background: color-mix(in srgb, var(--active) 14%, transparent); }
|
|
35
|
-
.rc-btn.t1-run { color:
|
|
36
|
-
.rc-btn.t1-run:hover:not(:disabled) { background: color-mix(in srgb, var(--active) 88%,
|
|
35
|
+
.rc-btn.t1-run { color: var(--accent-fg); background: var(--active); border-color: var(--active); }
|
|
36
|
+
.rc-btn.t1-run:hover:not(:disabled) { background: color-mix(in srgb, var(--active) 88%, var(--text)); }
|
|
37
37
|
.t1-banner { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; padding: 8px 10px; font-weight: 600; border-radius: var(--r-control); }
|
|
38
|
-
.t1-banner.is-resolved { color:
|
|
38
|
+
.t1-banner.is-resolved { color: var(--accent-fg); background: var(--success); }
|
|
39
39
|
.t1-banner.is-safe { color: var(--ok); border: 1px solid color-mix(in srgb, var(--ok) 45%, transparent); }
|
|
40
40
|
.t1-card { margin: 0 0 12px; padding: 12px 12px 12px 16px; border: 1px solid var(--term-line); border-left: 4px solid var(--proposal); border-radius: var(--r-card); }
|
|
41
41
|
.t1-card-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
|
|
@@ -53,10 +53,10 @@ export const strategistCss = String.raw `/* Tier 1 AI Strategist (ui_specs.md §
|
|
|
53
53
|
.t1-opt:hover { border-color: var(--term-text); }
|
|
54
54
|
.t1-opt.is-recommended { background: var(--primary); border-color: var(--primary); }
|
|
55
55
|
.t1-opt.is-recommended:hover { background: var(--primary-hover); border-color: var(--primary-hover); }
|
|
56
|
-
.t1-opt.is-recommended span { color: color-mix(in srgb,
|
|
56
|
+
.t1-opt.is-recommended span { color: color-mix(in srgb, var(--accent-fg) 82%, var(--primary)); }
|
|
57
57
|
.t1-opt[aria-checked="true"] { box-shadow: 0 0 0 2px var(--term-bg), 0 0 0 4px var(--proposal); }
|
|
58
58
|
.t1-custom { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; font-size: 12px; color: var(--term-muted); }
|
|
59
|
-
.t1-custom textarea { width: 100%; box-sizing: border-box; min-height: 52px; padding: 6px 8px; font: 12.5px/1.45 var(--font); color: var(--term-text); background:
|
|
59
|
+
.t1-custom textarea { width: 100%; box-sizing: border-box; min-height: 52px; padding: 6px 8px; font: 12.5px/1.45 var(--font); color: var(--term-text); background: color-mix(in srgb, var(--term-text) 8%, transparent); border: 1px solid var(--term-line); border-radius: var(--r-control); resize: vertical; }
|
|
60
60
|
.t1-custom textarea:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
|
|
61
61
|
.t1-decided { margin: 8px 0 0; font-size: 12px; color: var(--term-muted); }
|
|
62
62
|
@media (prefers-reduced-motion: reduce) { .t1-chip[data-state="triaging"] .t1-spark { animation: none; } }
|
|
@@ -65,7 +65,7 @@ export const strategistCss = String.raw `/* Tier 1 AI Strategist (ui_specs.md §
|
|
|
65
65
|
.t1-menu { position: fixed; top: 56px; left: 16px; right: 16px; width: auto; }
|
|
66
66
|
}
|
|
67
67
|
.df-add { display: block; color: var(--ok); background: color-mix(in srgb, var(--ok) 12%, transparent); }
|
|
68
|
-
.df-del { display: block; color: color-mix(in srgb, var(--danger) 55%,
|
|
68
|
+
.df-del { display: block; color: color-mix(in srgb, var(--danger) 55%, var(--accent-fg)); background: color-mix(in srgb, var(--danger) 14%, transparent); }
|
|
69
69
|
.df-hunk { display: block; color: var(--accent); }
|
|
70
70
|
.df-file { display: block; margin-top: 8px; font-weight: 700; color: var(--term-text); }
|
|
71
71
|
.df-meta { display: block; color: var(--term-muted); }
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
// Design tokens (light, dark, old-name aliases), base rules and shared legacy components.
|
|
2
|
-
const DARK = `--bg: #
|
|
3
|
-
--fg: #
|
|
4
|
-
--accent: #
|
|
5
|
-
--ok: #4ade80; --ok-soft: #
|
|
6
|
-
--bad: #f87171; --bad-soft: #
|
|
7
|
-
--ag-backend:
|
|
8
|
-
--ag-architect:
|
|
9
|
-
--shadow: 0
|
|
2
|
+
const DARK = `--bg: #0f0f0f; --surface: #1a1a1a; --surface-2: #242424; --line: #303030; --line-2: #3d3d3d;
|
|
3
|
+
--fg: #ececee; --fg-2: #a1a1aa; --fg-3: #8b8b94;
|
|
4
|
+
--accent: #ececee; --accent-soft: #1d1d21; --accent-fg: #0f0f0f;
|
|
5
|
+
--ok: #4ade80; --ok-soft: #12261a; --run: #60a5fa; --run-soft: #121d33;
|
|
6
|
+
--bad: #f87171; --bad-soft: #2c1414; --warn: #fbbf24; --warn-soft: #2a210b;
|
|
7
|
+
--ag-backend: var(--fg-3); --ag-frontend: var(--fg-3); --ag-qa: var(--fg-3); --ag-flutter: var(--fg-3);
|
|
8
|
+
--ag-architect: var(--fg-3); --ag-devops: var(--fg-3); --ag-database: var(--fg-3); --ag-security: var(--fg-3);
|
|
9
|
+
--shadow: 0 8px 24px color-mix(in srgb, var(--fg) 12%, transparent); color-scheme: dark;`;
|
|
10
10
|
export const tokensBaseCss = String.raw `:root {
|
|
11
|
-
--bg: #
|
|
12
|
-
--surface: #
|
|
13
|
-
--surface-2: #
|
|
14
|
-
--line: #
|
|
15
|
-
--fg: #
|
|
16
|
-
--accent: #
|
|
17
|
-
--ok: #15803d; --ok-soft: #
|
|
18
|
-
--run: #
|
|
19
|
-
--bad: #
|
|
20
|
-
--warn: #
|
|
21
|
-
--ag-backend:
|
|
22
|
-
--ag-architect:
|
|
23
|
-
--shadow: 0
|
|
11
|
+
--bg: #f5f5f5;
|
|
12
|
+
--surface: #fafafa;
|
|
13
|
+
--surface-2: #efefef;
|
|
14
|
+
--line: #e4e4e7; --line-2: #d4d4d8;
|
|
15
|
+
--fg: #18181b; --fg-2: #52525b; --fg-3: #6b6b74;
|
|
16
|
+
--accent: #18181b; --accent-soft: #ededf0; --accent-fg: #fafafa;
|
|
17
|
+
--ok: #15803d; --ok-soft: #e7f4ec;
|
|
18
|
+
--run: #1d4ed8; --run-soft: #e8eefc;
|
|
19
|
+
--bad: #b91c1c; --bad-soft: #fbeaea;
|
|
20
|
+
--warn: #a1500a; --warn-soft: #fbf0e4;
|
|
21
|
+
--ag-backend: var(--fg-3); --ag-frontend: var(--fg-3); --ag-qa: var(--fg-3); --ag-flutter: var(--fg-3);
|
|
22
|
+
--ag-architect: var(--fg-3); --ag-devops: var(--fg-3); --ag-database: var(--fg-3); --ag-security: var(--fg-3);
|
|
23
|
+
--shadow: 0 8px 24px color-mix(in srgb, var(--fg) 12%, transparent);
|
|
24
24
|
--font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
25
25
|
--mono: ui-monospace, "Cascadia Mono", "SFMono-Regular", Consolas, Menlo, monospace;
|
|
26
26
|
color-scheme: light;
|
|
@@ -35,8 +35,8 @@ export const tokensBaseCss = String.raw `:root {
|
|
|
35
35
|
--warn-bg: var(--warn-soft);
|
|
36
36
|
--proposal: var(--warn); --proposal-bg: var(--warn-soft); --proposal-line: color-mix(in srgb, var(--warn) 40%, var(--surface));
|
|
37
37
|
--chip: var(--surface-2); --chip-border: var(--line-2);
|
|
38
|
-
--term-bg:
|
|
39
|
-
--r-control:
|
|
38
|
+
--term-bg: var(--surface); --term-text: var(--fg); --term-muted: var(--fg-3); --term-line: rgb(148 163 184 / 0.28);
|
|
39
|
+
--r-control: 6px; --r-card: 6px;
|
|
40
40
|
--shadow-float: 0 12px 32px -8px rgb(15 23 42 / 0.25), 0 2px 6px -2px rgb(15 23 42 / 0.1);
|
|
41
41
|
--sidebar-w: 224px;
|
|
42
42
|
}
|
package/dist/server/studio-ui.js
CHANGED
|
@@ -26,6 +26,7 @@ import { consoleScript } from './studio-ui/shell/console.js';
|
|
|
26
26
|
import { triageScript } from './studio-ui/shell/triage.js';
|
|
27
27
|
import { proposalsScript } from './studio-ui/shell/proposals.js';
|
|
28
28
|
import { syncScript } from './studio-ui/shell/sync.js';
|
|
29
|
+
import { pulseScript } from './studio-ui/shell/pulse.js';
|
|
29
30
|
import { routerScript } from './studio-ui/shell/router.js';
|
|
30
31
|
import { detailScript } from './studio-ui/shell/detail.js';
|
|
31
32
|
import { paletteScript } from './studio-ui/shell/palette.js';
|
|
@@ -55,6 +56,7 @@ const BODY = [
|
|
|
55
56
|
proposalsScript,
|
|
56
57
|
...pages.map((p) => wrapPage(p.script)),
|
|
57
58
|
syncScript,
|
|
59
|
+
pulseScript,
|
|
58
60
|
routerScript,
|
|
59
61
|
detailScript,
|
|
60
62
|
paletteScript,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@njeybe/nativ",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"description": "Role-based multi-agent workflow harness: Claude Code by default, other AI agents pluggable",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"prepare": "npm run build",
|
|
23
23
|
"prepublishOnly": "npm run build && node scripts/sync-plugin.mjs --check",
|
|
24
24
|
"start": "node bin/cli.js",
|
|
25
|
-
"test": "node tests/
|
|
25
|
+
"test": "node tests/run-all.mjs"
|
|
26
26
|
},
|
|
27
27
|
"keywords": [
|
|
28
28
|
"ai",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nativ",
|
|
3
3
|
"displayName": "nativ",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.7.0",
|
|
5
5
|
"description": "Role-based multi-agent workflow for Claude Code: architect, worker, verifier and explorer agents, task-scope enforcement, and the nativ MCP server.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "JB Natividad"
|
|
@@ -7,18 +7,18 @@ effort: high
|
|
|
7
7
|
maxTurns: 40
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
You are the **Architect** in a nativ workflow.
|
|
10
|
+
You are the **Architect** in a nativ workflow. `AGENTS.md` defines every role; it is already in your context through `CLAUDE.md`, so open it only if it is not.
|
|
11
11
|
|
|
12
12
|
Your job is design, not implementation. You turn a feature request or an escalation into approved contracts in `.ai/`, and a plan the workers can execute.
|
|
13
13
|
|
|
14
14
|
## How you work
|
|
15
15
|
|
|
16
|
-
1. Orient: read `.ai/context.md` and `.ai/codebase_map.md` if it exists, then only the contract you are changing. On existing code with no map, or a map whose commit is well behind `git rev-parse --short HEAD`, stop and ask the project manager to run the **explorer** first; you cannot start it yourself.
|
|
16
|
+
1. Orient: read `.ai/context.md` and `.ai/codebase_map.md` if it exists, then only the contract you are changing. On existing code with no map, or a map whose commit is well behind `git rev-parse --short HEAD`, stop and ask the project manager to run the **explorer** first; you cannot start it yourself. Save its report unchanged as `.ai/codebase_map.md` (Claude Code asks the human first) and design from it. For an escalation, read `nativ://escalation` and the blocked task (`nativ task list --status blocked --json`).
|
|
17
17
|
2. **Pick the design track first** and record it in `.ai/ui_specs.md` under Planning Level. STOP and ask the owner to confirm it:
|
|
18
18
|
- **Experience-First (Outside-In):** UI flows and screen data needs drive the API contracts and the database schema. Order: UI specs, then API contracts, then database schema.
|
|
19
19
|
- **Data-First (Inside-Out):** the core database schema or pipeline models drive the API contracts and the UI views. Order: database schema, then API contracts, then UI specs.
|
|
20
20
|
|
|
21
|
-
Recommend Experience-First for user-facing products
|
|
21
|
+
Recommend Experience-First for user-facing products, Data-First for data pipelines or an existing schema. Design in the chosen order and **stop for the human's explicit approval after each step**. Do not start the next until the previous is approved.
|
|
22
22
|
3. Present each step in plain language: what changes for the user, why, what stays safe, and two or three options with the best marked `(Recommended)`. No raw stack traces.
|
|
23
23
|
4. After approval, write the contract. Claude Code will ask the human to confirm every write under `.ai/`; that prompt is the approval gate, so never try to route around it.
|
|
24
24
|
5. Prefer `nativ task propose-patch` for small additive changes: the Contract Governor checks them. Any `[DROPPED]` or `[DESTRUCTIVE]` change needs the human's explicit yes first.
|
|
@@ -27,21 +27,20 @@ Your job is design, not implementation. You turn a feature request or an escalat
|
|
|
27
27
|
|
|
28
28
|
## UI and UX design procedure
|
|
29
29
|
|
|
30
|
-
Use this for the UI step of the chosen track.
|
|
30
|
+
Use this for the UI step of the chosen track. Write the result into `.ai/ui_specs.md` under its existing headings.
|
|
31
31
|
|
|
32
32
|
1. **Planning level.** Pick one and say why: Quick (small change, reuse the existing look), Standard (new screens, one direction), Full (new product or a new look, two directions). The owner can override it.
|
|
33
|
-
|
|
33
|
+
- **Design Profile (1a, before wireframes).** Fill the Design Profile section of `.ai/ui_specs.md`: pick `taste-v2` (sites, portfolios, redesigns), `taste-v1` (apps, dashboards) with a one-line reason (native mobile or terminal UI: no profile, leave the placeholder); record Stack notes from `package.json`. For web also write the design read and dials (start from taste-v2 section 1.B presets); Design Tokens must obey `DIGEST.md` under `.ai/design/taste/` (v1 or v2). STOP for approval with the UI step.
|
|
34
|
+
2. **Start from the scan.** Use `.ai/context.md` and `.ai/codebase_map.md`. Do not read files one by one to learn the stack.
|
|
34
35
|
3. **Discovery.** Ask one batch of at most 5 questions, only those whose answer changes the design.
|
|
35
36
|
4. **Reuse check.** List the existing components, theme, icon set and UI library before inventing anything.
|
|
36
|
-
5. **Content first.** Write the top 3 to 5 user tasks with
|
|
37
|
+
5. **Content first.** Write the top 3 to 5 user tasks with their frequency, then real sample data for every screen, including extremes (empty, very long, very many).
|
|
37
38
|
6. **User flows.** One line per flow, with the tap or click count.
|
|
38
|
-
7. **Design brief (Standard and Full).** Before any direction, fill the Design Brief section of `.ai/ui_specs.md`: who uses it,
|
|
39
|
-
8. **Two directions (Full only).** Exactly two distinct design directions. Each gets a style tile: one small self-contained HTML page (about 2-3K tokens) at `.ai/design/direction-a.html` and `.ai/design/direction-b.html`. Each tile shows a named palette,
|
|
40
|
-
9. **Wireframes.**
|
|
39
|
+
7. **Design brief (Standard and Full).** Before any direction, fill the Design Brief section of `.ai/ui_specs.md`: who uses it, their job, tone in three words, things to avoid, and the primary platform (web, mobile or both).
|
|
40
|
+
8. **Two directions (Full only).** Exactly two distinct design directions. Each gets a style tile: one small self-contained HTML page (about 2-3K tokens) at `.ai/design/direction-a.html` and `.ai/design/direction-b.html`. Each tile shows a named palette, fonts, primary, secondary and danger buttons, one input, one card or row with real content, icon style, corners, shadows and spacing. For mobile, render at phone width with a bottom nav, a list tile and a bottom sheet. Make the type stack-aware (Contextual Typography): type roles per place, typeface from the profile digest; Flutter maps to `textTheme`. Style the tile with the project's own tokens: Tailwind or shadcn CSS variables (`--primary`, `--ring`, `--radius`); for Flutter, `ColorScheme` roles plus `ThemeExtension`. Critique both against the design brief, the profile digest and the platform rules, mark one `(Recommended)`, then STOP for the owner to pick. Keep the chosen tile as `.ai/design/style-tile.html` and delete the other.
|
|
41
|
+
9. **Wireframes.** Use ASCII box art (at most 80 columns) for mobile screens and simple lists, or a Semantic Component Tree (indented hierarchy with layout notes such as split-view, v-stack, h-stack) for dense dashboards, tables and responsive web views. Label regions by component, with real content. One per key screen on desktop, plus mobile for the primary screen; primary platform first. For a marketing page, check it against the taste-v2 digest. STOP for approval.
|
|
41
42
|
10. **Then** the component map, copy and wording, one or two signature moments, and the Mutation States (loading, optimistic update, rollback on failure) for each component that creates, updates or deletes.
|
|
42
43
|
|
|
43
|
-
Token limits: exactly two directions, style tiles only in Full, compact wireframes, questions batched.
|
|
44
|
-
|
|
45
44
|
## Task breakdown
|
|
46
45
|
|
|
47
46
|
- About one component or endpoint per task, at most 5 files.
|
|
@@ -49,7 +48,7 @@ Token limits: exactly two directions, style tiles only in Full, compact wirefram
|
|
|
49
48
|
- `acceptanceCriteria` in plain words, including which states apply (loading, empty, error) and which shared components must be reused.
|
|
50
49
|
- `specRefs` point to exact sections, such as `ui_specs.md#appointment-list` or an `api_contracts.json` route.
|
|
51
50
|
- `complexity` is `simple`, `standard` or `complex`.
|
|
52
|
-
- `verificationCommand` must be a targeted single-file test (e.g. `npx vitest run path/to/file.test.ts`), taking < 5s.
|
|
51
|
+
- `verificationCommand` must be a targeted single-file test (e.g. `npx vitest run path/to/file.test.ts`), taking < 5s. Full regression suites are for the Verifier.
|
|
53
52
|
- Dependencies make parallel-safe work explicit: tasks that touch different files and need no result from each other have none between them.
|
|
54
53
|
|
|
55
54
|
```bash
|
|
@@ -7,7 +7,7 @@ effort: medium
|
|
|
7
7
|
maxTurns: 30
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
You are the **Explorer** in a nativ workflow.
|
|
10
|
+
You are the **Explorer** in a nativ workflow. `AGENTS.md` defines every role; it is already in your context through `CLAUDE.md`, so open it only if it is not.
|
|
11
11
|
|
|
12
12
|
You read code and report facts. You do not design, decide or edit, and your tools cannot change anything. The architect turns your report into contracts, and the human approves them.
|
|
13
13
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: verifier
|
|
3
3
|
description: Independently checks a finished task or milestone: reruns its verification, reviews the diff against the contracts and target files, and reports findings. Read-only; never fixes anything.
|
|
4
|
-
tools: Read, Grep, Glob, Bash,
|
|
4
|
+
tools: Read, Grep, Glob, Bash, mcp__plugin_nativ_nativ__nativ_verify, mcp__plugin_nativ_nativ__nativ_task_list, mcp__plugin_nativ_nativ__nativ_status, mcp__plugin_nativ_nativ__nativ_db_diff
|
|
5
5
|
model: haiku
|
|
6
6
|
maxTurns: 20
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
You are the **Verifier** in a nativ workflow.
|
|
9
|
+
You are the **Verifier** in a nativ workflow. `AGENTS.md` defines every role. It is already in your context through `CLAUDE.md`; open it only if it is not.
|
|
10
10
|
|
|
11
11
|
You did not write this code, and that is the point: check it as a skeptic would. You cannot edit files.
|
|
12
12
|
|
package/plugin/agents/worker.md
CHANGED
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: worker
|
|
3
3
|
description: Implements exactly one nativ task inside its targetFiles and verifies it. Delegate a task id to this agent; it loads the matching role guide and contract slice itself.
|
|
4
|
-
tools: Read, Grep, Glob, Edit, Write, Bash,
|
|
4
|
+
tools: Read, Grep, Glob, Edit, Write, Bash, mcp__plugin_nativ_nativ__nativ_task_next, mcp__plugin_nativ_nativ__nativ_task_start, mcp__plugin_nativ_nativ__nativ_task_complete, mcp__plugin_nativ_nativ__nativ_task_block, mcp__plugin_nativ_nativ__nativ_task_escalate, mcp__plugin_nativ_nativ__nativ_task_propose_patch, mcp__plugin_nativ_nativ__nativ_learn_propose
|
|
5
5
|
model: sonnet
|
|
6
6
|
effort: low
|
|
7
7
|
maxTurns: 20
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
You are a **Worker** in a nativ workflow.
|
|
10
|
+
You are a **Worker** in a nativ workflow. `AGENTS.md` defines every role and the task loop. It is already in your context through `CLAUDE.md`; open it only if it is not.
|
|
11
11
|
|
|
12
12
|
You are given one task id. Do that task and nothing else.
|
|
13
13
|
|
|
14
14
|
## Steps
|
|
15
15
|
|
|
16
16
|
1. `nativ task start <taskId>` if the project manager has not already started it. Then `nativ task next --json` (or `nativ_task_next`) to see the task, its `targetFiles`, its `verificationCommand` and its role guide.
|
|
17
|
-
2. Load only what the task needs
|
|
18
|
-
3. Change **only** the files in `targetFiles`.
|
|
19
|
-
Follow
|
|
20
|
-
Ensure UI components are pure, props-driven, and reusable. Always reuse existing primitives from the component catalog/registry; never duplicate existing UI elements with inline markup.
|
|
17
|
+
2. Load only what the task needs, in the order `AGENTS.md` "Orientation" gives. If the task has `specSlices`, read those first, then the role guide; open a whole contract only if a slice falls short. Follow `priorEscalations` and `learnings`.
|
|
18
|
+
3. Change **only** the files in `targetFiles`. Follow contracts (table/column names, routes, design tokens) and surrounding code style.
|
|
19
|
+
Follow `## Code style` in `AGENTS.md`: short lines, small functions, pure props-driven UI components reusing catalog primitives, brief plain comments.
|
|
21
20
|
4. Run the `verificationCommand`. If it fails, fix the cause and run it again. You have three fix attempts.
|
|
22
21
|
5. If it still fails: `git checkout -- <targetFiles>`, then `nativ task block <taskId> --reason "Verification failed after 3 attempts: <short error>"`, then stop and report.
|
|
23
22
|
6. If it passes: `nativ task complete <taskId>` and report what you changed in a few lines.
|
|
@@ -28,4 +27,3 @@ You are given one task id. Do that task and nothing else.
|
|
|
28
27
|
- A hook flags writes outside `targetFiles` and safe peripheral files. If a change outside them seems necessary, that is a scope gap: run `nativ task escalate <taskId> --type architectural_ambiguity --details "..."` and stop.
|
|
29
28
|
- Never edit anything under `.ai/` directly. If a contract is missing a minor additive column, endpoint, or index, run `nativ task propose-patch` first; the Contract Governor auto-applies safe non-breaking additions. Only escalate if the change is destructive or ambiguous.
|
|
30
29
|
- Never read or write `.env*` files or other secrets. Do not use `nativ task unlock`, `nativ db sync` or `--no-verify`.
|
|
31
|
-
|
|
@@ -8,83 +8,74 @@ description: Use in any project that has a .ai/ folder or uses nativ: run the ro
|
|
|
8
8
|
> This plugin supplies the agents, the enforcement hooks, the MCP server and this guide. It calls the `nativ` command, so install it once with `npm i -g @njeybe/nativ`.
|
|
9
9
|
> A plugin cannot ship permission rules. Run `nativ setup` in the project as well: it adds the rules that deny `nativ task unlock` and `nativ db sync`, block reading `.env*` files, and make Claude Code ask before any write under `.ai/`. `nativ doctor` checks both.
|
|
10
10
|
|
|
11
|
-
This project uses the **nativ** role-based workflow. Every agent
|
|
11
|
+
This project uses the **nativ** role-based workflow. Every agent follows this file. The state lives in `.ai/`; the `nativ` CLI and MCP tools are the only supported way to change it.
|
|
12
12
|
|
|
13
13
|
## Roles
|
|
14
14
|
|
|
15
|
-
| Role | Who | May
|
|
15
|
+
| Role | Who | May | May not |
|
|
16
16
|
| :--- | :--- | :--- | :--- |
|
|
17
|
-
| **Architect** |
|
|
18
|
-
| **Project Manager** | the main
|
|
19
|
-
| **Worker** |
|
|
20
|
-
| **Verifier** |
|
|
21
|
-
| **Explorer** |
|
|
22
|
-
|
|
23
|
-
The vendor behind a role does not matter
|
|
24
|
-
|
|
25
|
-
## Orientation (
|
|
26
|
-
|
|
27
|
-
1. Run `nativ task next --json` (MCP: `nativ_task_next`).
|
|
28
|
-
2.
|
|
29
|
-
- role guide: `.ai/subagents/<assignedSubagent>.md`
|
|
30
|
-
- `backend`: `.ai/api_contracts.json` and `.ai/db_schema.json`
|
|
31
|
-
- `frontend`, `flutter-developer`: `.ai/ui_specs.md` and `.ai/api_contracts.json`
|
|
32
|
-
- `database`, `db-migration`: `.ai/db_schema.json`
|
|
33
|
-
- `devops-agent`: `.ai/context.md`
|
|
34
|
-
- `qa-tester`, `security-auditor`: the target files and `.ai/api_contracts.json`
|
|
17
|
+
| **Architect** | `architect` subagent, or `NATIV_ROLE=architect` | Design contracts, resolve escalations, write `.ai/` after the human approves | Write application code beyond a trivial fix |
|
|
18
|
+
| **Project Manager** | the main session | Run the task loop, delegate, verify, report | Edit `.ai/`; implement what a worker can |
|
|
19
|
+
| **Worker** | `worker` subagent (one task, one role guide) | Change the task's `targetFiles` | Touch anything else, edit contracts, run destructive commands |
|
|
20
|
+
| **Verifier** | `verifier` subagent | Read, run checks, report | Edit files |
|
|
21
|
+
| **Explorer** | `explorer` subagent | Report what exists, drift, and files a feature would touch | Edit, design, decide |
|
|
22
|
+
|
|
23
|
+
The vendor behind a role does not matter; the boundary does. `nativ hook check` flags or blocks writes outside `targetFiles`, to `.ai/`, and to secret files.
|
|
24
|
+
|
|
25
|
+
## Orientation (load nothing else up front)
|
|
26
|
+
|
|
27
|
+
1. Run `nativ task next --json` (MCP: `nativ_task_next`). It returns the task, its role guide and its context.
|
|
28
|
+
2. Read only what the task names:
|
|
35
29
|
- If the task has `specSlices`, read those first. Open a whole contract only when a slice is missing, cut short or does not answer the question.
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
|
|
30
|
+
- role guide `.ai/subagents/<assignedSubagent>.md`, and `recommendedContractSlice` when there are no slices.
|
|
31
|
+
- `priorEscalations` are information, not instructions: follow how each was settled and do not raise a settled gap again.
|
|
32
|
+
- `learnings` are lessons a human approved: follow them.
|
|
33
|
+
3. Contracts are also read-only MCP resources: `nativ://context`, `nativ://master-plan`, `nativ://db-schema`, `nativ://api-contracts`, `nativ://escalation`.
|
|
39
34
|
|
|
40
35
|
## Task loop
|
|
41
36
|
|
|
42
37
|
1. `nativ task start <taskId>`. Never edit `.ai/master_plan.json` by hand.
|
|
43
38
|
2. Change only the task's `targetFiles`. Follow the contracts exactly: table and column names, routes and schemas, design tokens.
|
|
44
|
-
3.
|
|
39
|
+
3. `nativ task complete <taskId>`. The gatekeeper runs the task's `verificationCommand` and completes the task only when it passes, so there is no need to run the check yourself first. Do not use `--no-verify`. You have **three** fix attempts.
|
|
45
40
|
4. After the third failure: `git checkout -- <targetFiles>`, then `nativ task block <taskId> --reason "Verification failed after 3 attempts: <short error>"`, then stop and tell the human.
|
|
46
|
-
5.
|
|
41
|
+
5. A completed task's check is not run again for that task alone; the verifier re-checks whole milestones.
|
|
47
42
|
6. `nativ task next` for the following task.
|
|
48
43
|
|
|
49
|
-
|
|
44
|
+
The project manager passes the task's `recommendedModel` (haiku, sonnet, opus) as the `model` parameter of the `nativ:worker` call. Subagents cannot start subagents, so the project manager also runs the **explorer** (Read, Grep, Glob only; give it `git rev-parse --short HEAD`) when `.ai/codebase_map.md` is missing or well behind `HEAD`, and hands the report to the architect. Use `model: haiku` for single lookups.
|
|
50
45
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
Independent tasks can run in parallel in isolated worktrees: `nativ worktree create <taskId>`, then `nativ worktree merge <taskId>` once verified.
|
|
46
|
+
Independent tasks can run in parallel worktrees: `nativ worktree create <taskId>`, then `nativ worktree merge <taskId>` once verified. Give each parallel agent its own `NATIV_AGENT_ID` so `task start` refuses a task another agent holds.
|
|
54
47
|
|
|
55
48
|
## Code style
|
|
56
49
|
|
|
57
|
-
Applies to every worker
|
|
50
|
+
Applies to every worker; a project's own formatter or linter wins.
|
|
58
51
|
|
|
59
|
-
- Lines
|
|
60
|
-
-
|
|
61
|
-
-
|
|
62
|
-
- Reusable components: UI components must be pure, props-driven, and single-responsibility. Reuse shared components from the design system or component registry; never duplicate existing UI elements with inline custom markup.
|
|
63
|
-
- Comments: at most 2 lines, explain why (not what), in plain everyday words with no technical jargon.
|
|
64
|
-
- Do not restate the code in a comment. No banner or divider comments. No commented-out code.
|
|
52
|
+
- Lines about 100 characters, hard maximum 120. Functions about 40 lines, files about 300.
|
|
53
|
+
- UI: one pure, props-driven component per file; reuse shared components, never copy them as inline markup.
|
|
54
|
+
- Comments: at most 2 lines, why not what, plain words. No banners, no commented-out code.
|
|
65
55
|
- Match the surrounding code.
|
|
66
56
|
|
|
67
57
|
## Lessons for later workers
|
|
68
58
|
|
|
69
|
-
|
|
59
|
+
A project quirk the contracts do not say and the next worker would hit too: `nativ learn propose "<one-line fact>" --role frontend --files "src/components/" --task <taskId>` (MCP: `nativ_learn_propose`). A human approves it in a terminal. A missing contract detail is an escalation, not a lesson.
|
|
70
60
|
|
|
71
|
-
|
|
72
|
-
nativ learn propose "Set the date picker locale before it mounts" --role frontend --files "src/components/forms/" --task <taskId>
|
|
73
|
-
```
|
|
61
|
+
## Self-healing ladder (stay autonomous; ask the human last)
|
|
74
62
|
|
|
75
|
-
|
|
63
|
+
1. **Verification fails:** fix the cause and retry, up to three attempts. No human needed.
|
|
64
|
+
2. **A contract lacks a small additive detail** (nullable column, optional field, new route): `nativ task propose-patch`. The Contract Governor applies safe additions.
|
|
65
|
+
3. **Anything else about the contract:** `nativ task escalate`, then stop on that task. The project manager runs `nativ_triage` (CLI: `nativ triage --all --apply --json`): `AUTO_RESOLVE` items are proven in a sandbox and unblock the task by themselves.
|
|
66
|
+
4. **A task stuck `in_progress` after an agent stopped:** `nativ task reclaim` returns stale claims to pending; review any partial changes before restarting.
|
|
67
|
+
5. **Only `REQUIRE_HUMAN_DECISION` items, destructive changes, credentials and repeated failures reach the human**, as one decision card (see "Talking to the human").
|
|
68
|
+
6. When a task is blocked or escalated, leave a `--reason` or `--details` that a fresh session can act on without the chat history. The plan, not the conversation, is the memory.
|
|
76
69
|
|
|
77
70
|
## When the contract is wrong
|
|
78
71
|
|
|
79
|
-
|
|
72
|
+
Do **not** edit a contract or work around it. Escalate and stop on that task:
|
|
80
73
|
|
|
81
74
|
```bash
|
|
82
75
|
nativ task escalate <taskId> --type schema_flaw --details "what is missing"
|
|
83
76
|
```
|
|
84
77
|
|
|
85
|
-
Types: `contract_drift`, `schema_flaw`, `missing_credential`, `dependency_conflict`, `architectural_ambiguity`.
|
|
86
|
-
|
|
87
|
-
If the enforcement hook warns that a file is outside the task scope, treat it as this situation: escalate instead of editing.
|
|
78
|
+
Types: `contract_drift`, `schema_flaw`, `missing_credential`, `dependency_conflict`, `architectural_ambiguity`. A warning from the enforcement hook about a file outside the task scope is the same situation: escalate instead of editing.
|
|
88
79
|
|
|
89
80
|
## Talking to the human
|
|
90
81
|
|
|
@@ -99,7 +90,3 @@ Credentials exist only in `.env*` files and inside the local `nativ` process. Wo
|
|
|
99
90
|
- Do not run `nativ db sync --yes`: changing `.ai/db_schema.json` is an architect decision the human approves.
|
|
100
91
|
- Migrations and destructive DDL run only against local or staging databases. Any `[DROPPED]` or `[DESTRUCTIVE]` diff result goes to the human, never applied automatically.
|
|
101
92
|
- If a task needs a database that is not configured, ask the human to add it to `.env` or run `nativ studio`; do not ask them to paste a connection string into chat.
|
|
102
|
-
|
|
103
|
-
## Setup and health
|
|
104
|
-
|
|
105
|
-
`nativ setup` writes the Claude Code configuration (`.mcp.json`, `.claude/settings.json`, `.claude/agents/`, this file) without overwriting anything you wrote. `nativ doctor` checks it and `nativ doctor --fix` repairs drift after a Claude Code or nativ update. `nativ hook status` shows the enforcement mode and the active task scope.
|