@nac3/forge-cli 0.2.1-alpha.60 → 1.0.1
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/README.md +5 -1
- package/dist/agents/bridge.d.ts.map +1 -1
- package/dist/agents/bridge.js +27 -0
- package/dist/agents/bridge.js.map +1 -1
- package/dist/agents/config_resolver.d.ts.map +1 -1
- package/dist/agents/config_resolver.js +15 -15
- package/dist/agents/config_resolver.js.map +1 -1
- package/dist/agents/runner.d.ts +8 -0
- package/dist/agents/runner.d.ts.map +1 -1
- package/dist/agents/runner.js +58 -11
- package/dist/agents/runner.js.map +1 -1
- package/dist/agents/system_prompt.d.ts.map +1 -1
- package/dist/agents/system_prompt.js +2 -1
- package/dist/agents/system_prompt.js.map +1 -1
- package/dist/bin/yf.d.ts.map +1 -1
- package/dist/bin/yf.js +18 -0
- package/dist/bin/yf.js.map +1 -1
- package/dist/chat/claude.d.ts +13 -0
- package/dist/chat/claude.d.ts.map +1 -1
- package/dist/chat/claude.js +95 -10
- package/dist/chat/claude.js.map +1 -1
- package/dist/chat/claude_cli.d.ts +10 -0
- package/dist/chat/claude_cli.d.ts.map +1 -1
- package/dist/chat/claude_cli.js +97 -16
- package/dist/chat/claude_cli.js.map +1 -1
- package/dist/chat/completion_hallucination_detector.d.ts +11 -0
- package/dist/chat/completion_hallucination_detector.d.ts.map +1 -1
- package/dist/chat/completion_hallucination_detector.js +37 -2
- package/dist/chat/completion_hallucination_detector.js.map +1 -1
- package/dist/chat/doctrine_digest.d.ts.map +1 -1
- package/dist/chat/doctrine_digest.js +10 -6
- package/dist/chat/doctrine_digest.js.map +1 -1
- package/dist/chat/panel.d.ts.map +1 -1
- package/dist/chat/panel.js +923 -50
- package/dist/chat/panel.js.map +1 -1
- package/dist/chat/refusal_detector.d.ts.map +1 -1
- package/dist/chat/refusal_detector.js +2 -1
- package/dist/chat/refusal_detector.js.map +1 -1
- package/dist/chat/server.d.ts +1 -0
- package/dist/chat/server.d.ts.map +1 -1
- package/dist/chat/server.js +960 -73
- package/dist/chat/server.js.map +1 -1
- package/dist/chat/session_projects.d.ts +31 -0
- package/dist/chat/session_projects.d.ts.map +1 -0
- package/dist/chat/session_projects.js +36 -0
- package/dist/chat/session_projects.js.map +1 -0
- package/dist/chat/session_store.d.ts +32 -0
- package/dist/chat/session_store.d.ts.map +1 -0
- package/dist/chat/session_store.js +58 -0
- package/dist/chat/session_store.js.map +1 -0
- package/dist/chat/tooling_section.d.ts +11 -0
- package/dist/chat/tooling_section.d.ts.map +1 -0
- package/dist/chat/tooling_section.js +70 -0
- package/dist/chat/tooling_section.js.map +1 -0
- package/dist/chat/tools/app_backend_dispatch.d.ts.map +1 -1
- package/dist/chat/tools/app_backend_dispatch.js +44 -1
- package/dist/chat/tools/app_backend_dispatch.js.map +1 -1
- package/dist/chat/tools/fs_editor.d.ts.map +1 -1
- package/dist/chat/tools/fs_editor.js +53 -3
- package/dist/chat/tools/fs_editor.js.map +1 -1
- package/dist/chat/tools/graph.js +2 -2
- package/dist/chat/tools/graph.js.map +1 -1
- package/dist/chat/tools/keys.d.ts.map +1 -1
- package/dist/chat/tools/keys.js +5 -18
- package/dist/chat/tools/keys.js.map +1 -1
- package/dist/chat/tools/nac3_invoke.d.ts.map +1 -1
- package/dist/chat/tools/nac3_invoke.js +16 -7
- package/dist/chat/tools/nac3_invoke.js.map +1 -1
- package/dist/chat/tools/shell.d.ts +6 -0
- package/dist/chat/tools/shell.d.ts.map +1 -1
- package/dist/chat/tools/shell.js +39 -0
- package/dist/chat/tools/shell.js.map +1 -1
- package/dist/chat/tools/workflow.d.ts +20 -0
- package/dist/chat/tools/workflow.d.ts.map +1 -1
- package/dist/chat/tools/workflow.js +98 -0
- package/dist/chat/tools/workflow.js.map +1 -1
- package/dist/chat/tools.d.ts.map +1 -1
- package/dist/chat/tools.js +79 -1
- package/dist/chat/tools.js.map +1 -1
- package/dist/chat/turn_control.d.ts +42 -0
- package/dist/chat/turn_control.d.ts.map +1 -0
- package/dist/chat/turn_control.js +53 -0
- package/dist/chat/turn_control.js.map +1 -0
- package/dist/commands/brain.js +1 -1
- package/dist/commands/chat.d.ts.map +1 -1
- package/dist/commands/chat.js +61 -10
- package/dist/commands/chat.js.map +1 -1
- package/dist/commands/graph.js +9 -9
- package/dist/commands/graph.js.map +1 -1
- package/dist/commands/keys_setup.d.ts +10 -28
- package/dist/commands/keys_setup.d.ts.map +1 -1
- package/dist/commands/keys_setup.js +54 -228
- package/dist/commands/keys_setup.js.map +1 -1
- package/dist/commands/license.d.ts.map +1 -1
- package/dist/commands/license.js +52 -28
- package/dist/commands/license.js.map +1 -1
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +62 -6
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/mobile.d.ts +1 -1
- package/dist/commands/mobile.d.ts.map +1 -1
- package/dist/commands/mobile.js +32 -28
- package/dist/commands/mobile.js.map +1 -1
- package/dist/commands/onboard.d.ts +19 -0
- package/dist/commands/onboard.d.ts.map +1 -0
- package/dist/commands/onboard.js +126 -0
- package/dist/commands/onboard.js.map +1 -0
- package/dist/commands/pending.d.ts.map +1 -1
- package/dist/commands/pending.js +25 -1
- package/dist/commands/pending.js.map +1 -1
- package/dist/commands/projects.js +25 -1
- package/dist/commands/projects.js.map +1 -1
- package/dist/commands/review-screens.js +28 -1
- package/dist/commands/review-screens.js.map +1 -1
- package/dist/commands/workflow.d.ts +18 -0
- package/dist/commands/workflow.d.ts.map +1 -0
- package/dist/commands/workflow.js +253 -0
- package/dist/commands/workflow.js.map +1 -0
- package/dist/core/brain_config.d.ts +2 -0
- package/dist/core/brain_config.d.ts.map +1 -1
- package/dist/core/brain_config.js +18 -3
- package/dist/core/brain_config.js.map +1 -1
- package/dist/core/cf_tunnel.d.ts.map +1 -1
- package/dist/core/cf_tunnel.js +8 -2
- package/dist/core/cf_tunnel.js.map +1 -1
- package/dist/core/cost_router.d.ts.map +1 -1
- package/dist/core/cost_router.js +11 -2
- package/dist/core/cost_router.js.map +1 -1
- package/dist/core/desktop_open.d.ts +16 -0
- package/dist/core/desktop_open.d.ts.map +1 -0
- package/dist/core/desktop_open.js +114 -0
- package/dist/core/desktop_open.js.map +1 -0
- package/dist/core/keys_envelope.d.ts.map +1 -1
- package/dist/core/keys_envelope.js +5 -1
- package/dist/core/keys_envelope.js.map +1 -1
- package/dist/core/limits_config.d.ts +5 -0
- package/dist/core/limits_config.d.ts.map +1 -1
- package/dist/core/limits_config.js +5 -0
- package/dist/core/limits_config.js.map +1 -1
- package/dist/core/logger.d.ts.map +1 -1
- package/dist/core/logger.js +3 -0
- package/dist/core/logger.js.map +1 -1
- package/dist/core/pairing.d.ts +6 -0
- package/dist/core/pairing.d.ts.map +1 -1
- package/dist/core/pairing.js +41 -2
- package/dist/core/pairing.js.map +1 -1
- package/dist/core/provider_keys.d.ts.map +1 -1
- package/dist/core/provider_keys.js +25 -12
- package/dist/core/provider_keys.js.map +1 -1
- package/dist/core/provider_models.js +1 -1
- package/dist/deploy/cloudflare.d.ts.map +1 -1
- package/dist/deploy/cloudflare.js +13 -2
- package/dist/deploy/cloudflare.js.map +1 -1
- package/dist/design/yujin_design_resolver.d.ts +16 -0
- package/dist/design/yujin_design_resolver.d.ts.map +1 -1
- package/dist/design/yujin_design_resolver.js +103 -20
- package/dist/design/yujin_design_resolver.js.map +1 -1
- package/dist/docs/doctrine/default-design-system.md +32 -0
- package/dist/docs/doctrine/office-tools.md +20 -0
- package/dist/docs/doctrine/pizarron.md +40 -0
- package/dist/docs/doctrine/verb-composition.md +16 -0
- package/dist/docs/doctrine/workflow-kinds.md +39 -22
- package/dist/docs/doctrine/workflow.md +12 -4
- package/dist/license/auto_sync.d.ts +22 -0
- package/dist/license/auto_sync.d.ts.map +1 -0
- package/dist/license/auto_sync.js +91 -0
- package/dist/license/auto_sync.js.map +1 -0
- package/dist/license/handle_key.d.ts +32 -0
- package/dist/license/handle_key.d.ts.map +1 -0
- package/dist/license/handle_key.js +56 -0
- package/dist/license/handle_key.js.map +1 -0
- package/dist/license/hito4_client.d.ts.map +1 -1
- package/dist/license/hito4_client.js +63 -25
- package/dist/license/hito4_client.js.map +1 -1
- package/dist/llm/gemini_client.d.ts.map +1 -1
- package/dist/llm/gemini_client.js +5 -2
- package/dist/llm/gemini_client.js.map +1 -1
- package/dist/llm/managed_client.d.ts.map +1 -1
- package/dist/llm/managed_client.js +14 -9
- package/dist/llm/managed_client.js.map +1 -1
- package/dist/mcp/plan_bridges.d.ts +17 -0
- package/dist/mcp/plan_bridges.d.ts.map +1 -0
- package/dist/mcp/plan_bridges.js +119 -0
- package/dist/mcp/plan_bridges.js.map +1 -0
- package/dist/migrate/ai-apply.d.ts.map +1 -1
- package/dist/migrate/ai-apply.js +25 -2
- package/dist/migrate/ai-apply.js.map +1 -1
- package/dist/nac3/internal_manifest.d.ts.map +1 -1
- package/dist/nac3/internal_manifest.js +200 -10
- package/dist/nac3/internal_manifest.js.map +1 -1
- package/dist/nac3/verb_tier_map.d.ts.map +1 -1
- package/dist/nac3/verb_tier_map.js +3 -0
- package/dist/nac3/verb_tier_map.js.map +1 -1
- package/dist/onboarding/concierge_client.d.ts +34 -0
- package/dist/onboarding/concierge_client.d.ts.map +1 -0
- package/dist/onboarding/concierge_client.js +80 -0
- package/dist/onboarding/concierge_client.js.map +1 -0
- package/dist/onboarding/next_step.d.ts +32 -0
- package/dist/onboarding/next_step.d.ts.map +1 -0
- package/dist/onboarding/next_step.js +60 -0
- package/dist/onboarding/next_step.js.map +1 -0
- package/dist/pending/store.d.ts +7 -0
- package/dist/pending/store.d.ts.map +1 -1
- package/dist/pending/store.js +19 -0
- package/dist/pending/store.js.map +1 -1
- package/dist/pending/types.d.ts +20 -0
- package/dist/pending/types.d.ts.map +1 -1
- package/dist/pending/types.js.map +1 -1
- package/dist/reader/parsers/epub.d.ts.map +1 -1
- package/dist/reader/parsers/epub.js +6 -1
- package/dist/reader/parsers/epub.js.map +1 -1
- package/dist/relay/board_snapshot.d.ts +69 -0
- package/dist/relay/board_snapshot.d.ts.map +1 -0
- package/dist/relay/board_snapshot.js +149 -0
- package/dist/relay/board_snapshot.js.map +1 -0
- package/dist/relay/command_consumer.d.ts +97 -0
- package/dist/relay/command_consumer.d.ts.map +1 -0
- package/dist/relay/command_consumer.js +135 -0
- package/dist/relay/command_consumer.js.map +1 -0
- package/dist/relay/mock_relay.d.ts +34 -0
- package/dist/relay/mock_relay.d.ts.map +1 -0
- package/dist/relay/mock_relay.js +93 -0
- package/dist/relay/mock_relay.js.map +1 -0
- package/dist/relay/relay_client.d.ts +28 -0
- package/dist/relay/relay_client.d.ts.map +1 -0
- package/dist/relay/relay_client.js +80 -0
- package/dist/relay/relay_client.js.map +1 -0
- package/dist/relay/relay_publisher.d.ts +59 -0
- package/dist/relay/relay_publisher.d.ts.map +1 -0
- package/dist/relay/relay_publisher.js +101 -0
- package/dist/relay/relay_publisher.js.map +1 -0
- package/dist/relay/types.d.ts +54 -0
- package/dist/relay/types.d.ts.map +1 -0
- package/dist/relay/types.js +8 -0
- package/dist/relay/types.js.map +1 -0
- package/dist/semantic_graph/ast_extract.d.ts +5 -0
- package/dist/semantic_graph/ast_extract.d.ts.map +1 -1
- package/dist/semantic_graph/ast_extract.js +46 -0
- package/dist/semantic_graph/ast_extract.js.map +1 -1
- package/dist/semantic_graph/derive.d.ts +12 -0
- package/dist/semantic_graph/derive.d.ts.map +1 -1
- package/dist/semantic_graph/derive.js +325 -6
- package/dist/semantic_graph/derive.js.map +1 -1
- package/dist/semantic_graph/store.d.ts +9 -0
- package/dist/semantic_graph/store.d.ts.map +1 -1
- package/dist/semantic_graph/store.js +23 -1
- package/dist/semantic_graph/store.js.map +1 -1
- package/dist/semantic_graph/types.d.ts +1 -1
- package/dist/semantic_graph/types.d.ts.map +1 -1
- package/dist/support/github_dispatcher.d.ts.map +1 -1
- package/dist/support/github_dispatcher.js +30 -2
- package/dist/support/github_dispatcher.js.map +1 -1
- package/dist/tasks/supervisor.d.ts +88 -0
- package/dist/tasks/supervisor.d.ts.map +1 -0
- package/dist/tasks/supervisor.js +308 -0
- package/dist/tasks/supervisor.js.map +1 -0
- package/dist/tasks/task_type.d.ts +11 -0
- package/dist/tasks/task_type.d.ts.map +1 -0
- package/dist/tasks/task_type.js +21 -0
- package/dist/tasks/task_type.js.map +1 -0
- package/dist/vault/store.d.ts.map +1 -1
- package/dist/vault/store.js +6 -1
- package/dist/vault/store.js.map +1 -1
- package/dist/version.d.ts +3 -5
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +3 -5
- package/dist/version.js.map +1 -1
- package/dist/voice/providers/google.d.ts.map +1 -1
- package/dist/voice/providers/google.js +6 -4
- package/dist/voice/providers/google.js.map +1 -1
- package/dist/workflow/config.d.ts +43 -0
- package/dist/workflow/config.d.ts.map +1 -0
- package/dist/workflow/config.js +199 -0
- package/dist/workflow/config.js.map +1 -0
- package/dist/workflow/instances.d.ts +40 -0
- package/dist/workflow/instances.d.ts.map +1 -0
- package/dist/workflow/instances.js +122 -0
- package/dist/workflow/instances.js.map +1 -0
- package/dist/workflow/multi_view.d.ts +27 -0
- package/dist/workflow/multi_view.d.ts.map +1 -0
- package/dist/workflow/multi_view.js +76 -0
- package/dist/workflow/multi_view.js.map +1 -0
- package/dist/workflow/orchestrator.d.ts +111 -0
- package/dist/workflow/orchestrator.d.ts.map +1 -0
- package/dist/workflow/orchestrator.js +241 -0
- package/dist/workflow/orchestrator.js.map +1 -0
- package/docs/doctrine/default-design-system.md +32 -0
- package/docs/doctrine/office-tools.md +20 -0
- package/docs/doctrine/pizarron.md +40 -0
- package/docs/doctrine/verb-composition.md +16 -0
- package/docs/doctrine/workflow-kinds.md +39 -22
- package/docs/doctrine/workflow.md +12 -4
- package/package.json +2 -1
- package/src/i18n/catalogs/ar.json +223 -210
- package/src/i18n/catalogs/de.json +223 -210
- package/src/i18n/catalogs/en.json +223 -210
- package/src/i18n/catalogs/es.json +223 -210
- package/src/i18n/catalogs/fr.json +223 -210
- package/src/i18n/catalogs/hi.json +223 -210
- package/src/i18n/catalogs/it.json +223 -210
- package/src/i18n/catalogs/ja.json +223 -210
- package/src/i18n/catalogs/pt.json +223 -210
- package/src/i18n/catalogs/zh.json +223 -210
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { WorkflowKind } from './definitions.js';
|
|
2
|
+
export interface WorkflowTaskView {
|
|
3
|
+
id: string;
|
|
4
|
+
title: string;
|
|
5
|
+
closed: boolean;
|
|
6
|
+
order: number;
|
|
7
|
+
ad_hoc: boolean;
|
|
8
|
+
category?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface WorkflowStageTasksView {
|
|
11
|
+
id: string;
|
|
12
|
+
title: string;
|
|
13
|
+
tasks: WorkflowTaskView[];
|
|
14
|
+
}
|
|
15
|
+
export interface WorkflowCardView {
|
|
16
|
+
code: string;
|
|
17
|
+
name: string;
|
|
18
|
+
kind: WorkflowKind;
|
|
19
|
+
status: 'open' | 'closed';
|
|
20
|
+
done: number;
|
|
21
|
+
total: number;
|
|
22
|
+
stages: WorkflowStageTasksView[];
|
|
23
|
+
}
|
|
24
|
+
/** Build the per-workflow card views (stages -> ordered tasks) for a
|
|
25
|
+
* project. Best-effort: a missing store yields an empty list. */
|
|
26
|
+
export declare function computeWorkflowsView(slug: string, status?: 'open' | 'all'): Promise<WorkflowCardView[]>;
|
|
27
|
+
//# sourceMappingURL=multi_view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi_view.d.ts","sourceRoot":"","sources":["../../src/workflow/multi_view.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,gBAAgB,EAAE,CAAC;CAC3B;AACD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,sBAAsB,EAAE,CAAC;CAClC;AAOD;kEACkE;AAClE,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,GAAG,KAAc,GAC5C,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA8C7B"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-workflow view (PND-094 ext).
|
|
3
|
+
*
|
|
4
|
+
* The old computeWorkflowView produced ONE workflow from the legacy
|
|
5
|
+
* WorkflowState. The new model has several coexisting WorkflowInstances
|
|
6
|
+
* whose TASKS are pendings (linked via PendingItem.workflow). This
|
|
7
|
+
* crosses the instances with their task-pendings to produce, per
|
|
8
|
+
* workflow, its stages each with its ordered tasks -- the structure both
|
|
9
|
+
* the desktop panel and the mobile board render.
|
|
10
|
+
*
|
|
11
|
+
* ASCII-only.
|
|
12
|
+
*/
|
|
13
|
+
import { listInstances } from './instances.js';
|
|
14
|
+
import { listPending } from '../pending/store.js';
|
|
15
|
+
function stripCode(code, title) {
|
|
16
|
+
const p = '[' + code + '] ';
|
|
17
|
+
return title.startsWith(p) ? title.slice(p.length) : title;
|
|
18
|
+
}
|
|
19
|
+
/** Build the per-workflow card views (stages -> ordered tasks) for a
|
|
20
|
+
* project. Best-effort: a missing store yields an empty list. */
|
|
21
|
+
export async function computeWorkflowsView(slug, status = 'open') {
|
|
22
|
+
let instances;
|
|
23
|
+
try {
|
|
24
|
+
instances = await listInstances(slug, status === 'all' ? 'all' : 'open');
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
if (instances.length === 0)
|
|
30
|
+
return [];
|
|
31
|
+
let allPend;
|
|
32
|
+
try {
|
|
33
|
+
allPend = await listPending(slug, { status: 'all' });
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
allPend = [];
|
|
37
|
+
}
|
|
38
|
+
const out = [];
|
|
39
|
+
for (const inst of instances) {
|
|
40
|
+
const tasks = allPend.filter((p) => p.workflow?.code === inst.code);
|
|
41
|
+
const byStage = new Map();
|
|
42
|
+
for (const t of tasks) {
|
|
43
|
+
const w = t.workflow;
|
|
44
|
+
const tv = {
|
|
45
|
+
id: t.id,
|
|
46
|
+
title: stripCode(inst.code, t.title),
|
|
47
|
+
closed: t.closed_at !== undefined,
|
|
48
|
+
order: w.order,
|
|
49
|
+
ad_hoc: w.ad_hoc === true,
|
|
50
|
+
...(t.category ? { category: t.category } : {}),
|
|
51
|
+
};
|
|
52
|
+
const arr = byStage.get(w.stage_id) ?? [];
|
|
53
|
+
arr.push(tv);
|
|
54
|
+
byStage.set(w.stage_id, arr);
|
|
55
|
+
}
|
|
56
|
+
const stages = inst.stages.map((s) => ({
|
|
57
|
+
id: s.id, title: s.title,
|
|
58
|
+
tasks: (byStage.get(s.id) ?? []).sort((a, b) => a.order - b.order),
|
|
59
|
+
}));
|
|
60
|
+
/* Ad-hoc tasks may use a stage_id that is not in the instance
|
|
61
|
+
* skeleton -- surface them under their own stage so nothing is lost. */
|
|
62
|
+
const known = new Set(inst.stages.map((s) => s.id));
|
|
63
|
+
for (const [sid, arr] of byStage) {
|
|
64
|
+
if (!known.has(sid))
|
|
65
|
+
stages.push({ id: sid, title: sid, tasks: arr.sort((a, b) => a.order - b.order) });
|
|
66
|
+
}
|
|
67
|
+
out.push({
|
|
68
|
+
code: inst.code, name: inst.name, kind: inst.kind, status: inst.status,
|
|
69
|
+
done: tasks.filter((t) => t.closed_at !== undefined).length,
|
|
70
|
+
total: tasks.length,
|
|
71
|
+
stages,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return out;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=multi_view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi_view.js","sourceRoot":"","sources":["../../src/workflow/multi_view.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AA0BlD,SAAS,SAAS,CAAC,IAAY,EAAE,KAAa;IAC5C,MAAM,CAAC,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;IAC5B,OAAO,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC7D,CAAC;AAED;kEACkE;AAClE,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAY,EAAE,SAAyB,MAAM;IAE7C,IAAI,SAAoD,CAAC;IACzD,IAAI,CAAC;QAAC,SAAS,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAAC,CAAC;IACjF,MAAM,CAAC;QAAC,OAAO,EAAE,CAAC;IAAC,CAAC;IACpB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEtC,IAAI,OAAgD,CAAC;IACrD,IAAI,CAAC;QAAC,OAAO,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAAC,CAAC;IAC7D,MAAM,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;IAAC,CAAC;IAEvB,MAAM,GAAG,GAAuB,EAAE,CAAC;IACnC,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC;QACpE,MAAM,OAAO,GAAG,IAAI,GAAG,EAA8B,CAAC;QACtD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,CAAC,CAAC,QAAS,CAAC;YACtB,MAAM,EAAE,GAAqB;gBAC3B,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC;gBACpC,MAAM,EAAE,CAAC,CAAC,SAAS,KAAK,SAAS;gBACjC,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,MAAM,EAAE,CAAC,CAAC,MAAM,KAAK,IAAI;gBACzB,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAChD,CAAC;YACF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC1C,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC/B,CAAC;QACD,MAAM,MAAM,GAA6B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC/D,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK;YACxB,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;SACnE,CAAC,CAAC,CAAC;QACJ;gFACwE;QACxE,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACpD,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,OAAO,EAAE,CAAC;YACjC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC1G,CAAC;QACD,GAAG,CAAC,IAAI,CAAC;YACP,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM;YACtE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,MAAM;YAC3D,KAAK,EAAE,KAAK,CAAC,MAAM;YACnB,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { type WorkflowInstance } from './instances.js';
|
|
2
|
+
import type { WorkflowKind } from './definitions.js';
|
|
3
|
+
import type { PendingItem, PendingCategory } from '../pending/types.js';
|
|
4
|
+
/** True when the project already has an implementation. Pure fs scan:
|
|
5
|
+
* a package.json / known source dir, or >3 real top-level entries. */
|
|
6
|
+
export declare function projectHasCode(projectRoot: string): Promise<boolean>;
|
|
7
|
+
export interface ClassifyResult {
|
|
8
|
+
kind: WorkflowKind;
|
|
9
|
+
confidence: number;
|
|
10
|
+
rationale: string;
|
|
11
|
+
/** True when confidence is low -- the caller must ASK the user
|
|
12
|
+
* (decision: on doubt, confirm). */
|
|
13
|
+
needs_confirm: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function classifyForProject(projectRoot: string, requestText: string): Promise<ClassifyResult>;
|
|
16
|
+
export interface InstantiateInput {
|
|
17
|
+
slug: string;
|
|
18
|
+
projectRoot: string;
|
|
19
|
+
kind: WorkflowKind;
|
|
20
|
+
name: string;
|
|
21
|
+
}
|
|
22
|
+
export interface InstantiateResult {
|
|
23
|
+
instance: WorkflowInstance;
|
|
24
|
+
tasks: PendingItem[];
|
|
25
|
+
}
|
|
26
|
+
/** Create a workflow instance + spawn one pending per canonical task,
|
|
27
|
+
* in mandatory order. Seeds the editable config (+ DR snapshot) first. */
|
|
28
|
+
export declare function instantiateWorkflow(input: InstantiateInput): Promise<InstantiateResult>;
|
|
29
|
+
/** Spawn ONE pending per canonical task of the instance's kind, in
|
|
30
|
+
* mandatory order, linked to the given EXISTING instance. The primitive
|
|
31
|
+
* shared by instantiateWorkflow and by upgrading a backlog-only shell so
|
|
32
|
+
* every phase gets its canonical scaffold (triage/diseno/.../cerrar). */
|
|
33
|
+
export declare function seedCanonicalTasks(slug: string, projectRoot: string, instance: WorkflowInstance): Promise<PendingItem[]>;
|
|
34
|
+
/** Create a workflow instance WITHOUT spawning canonical task pendings.
|
|
35
|
+
* Used when the tasks already exist (a backlog folded into a brownfield
|
|
36
|
+
* workflow via attachPendingsToWorkflow). */
|
|
37
|
+
export declare function createWorkflowShell(input: InstantiateInput): Promise<WorkflowInstance>;
|
|
38
|
+
/** Fold EXISTING pendings into a workflow as its tasks, in the given
|
|
39
|
+
* order (default: the order they are passed). Each gets a workflow
|
|
40
|
+
* link with a sequential `order` after any tasks already on the
|
|
41
|
+
* instance. Skips ids that do not exist. Returns the linked items. */
|
|
42
|
+
export declare function attachPendingsToWorkflow(input: {
|
|
43
|
+
slug: string;
|
|
44
|
+
code: string;
|
|
45
|
+
ids: string[];
|
|
46
|
+
stage_id?: string;
|
|
47
|
+
}): Promise<PendingItem[]>;
|
|
48
|
+
export interface RouteInput {
|
|
49
|
+
slug: string;
|
|
50
|
+
projectRoot: string;
|
|
51
|
+
kind: WorkflowKind;
|
|
52
|
+
name: string;
|
|
53
|
+
}
|
|
54
|
+
/** Find an OPEN instance with the same name (same initiative) or create
|
|
55
|
+
* a new one. Coexistence: instances are keyed by code + name, so two
|
|
56
|
+
* distinct initiatives of the same kind run side by side. */
|
|
57
|
+
export declare function routeRequest(input: RouteInput): Promise<{
|
|
58
|
+
instance: WorkflowInstance;
|
|
59
|
+
created: boolean;
|
|
60
|
+
}>;
|
|
61
|
+
export interface MapHookResult {
|
|
62
|
+
created: boolean;
|
|
63
|
+
kind?: WorkflowKind;
|
|
64
|
+
code?: string;
|
|
65
|
+
name?: string;
|
|
66
|
+
reason: string;
|
|
67
|
+
}
|
|
68
|
+
/** On mapping a project, ensure the RIGHT workflow exists -- deterministic,
|
|
69
|
+
* no LLM. greenfield (no code) -> instantiate the build skeleton (tasks
|
|
70
|
+
* spawned). brownfield (has code) -> an evolutive maintenance workflow
|
|
71
|
+
* WITH its canonical tasks per phase (triage/diseno/implementar/validar/
|
|
72
|
+
* docs/cerrar) spawned, so every phase has its canonical scaffold and no
|
|
73
|
+
* phase looks empty; ad-hoc backlog items attach under Implementar.
|
|
74
|
+
* Idempotent: a no-op when the project already has an open workflow, so
|
|
75
|
+
* it is safe to call on every scan/add. Best-effort -- callers must not
|
|
76
|
+
* let it break the map. */
|
|
77
|
+
export declare function ensureWorkflowForMappedProject(slug: string, projectRoot: string, projectName?: string): Promise<MapHookResult>;
|
|
78
|
+
export interface AddTaskInput {
|
|
79
|
+
slug: string;
|
|
80
|
+
code: string;
|
|
81
|
+
title: string;
|
|
82
|
+
body?: string;
|
|
83
|
+
category?: PendingCategory;
|
|
84
|
+
stage_id?: string;
|
|
85
|
+
priority?: number;
|
|
86
|
+
}
|
|
87
|
+
/** Append a task to a running workflow at the END of its order. Used
|
|
88
|
+
* for corrective/evolutive tasks the user adds at discretion during a
|
|
89
|
+
* workflow, AND for tasks the brain decides to add mid-execution. */
|
|
90
|
+
export declare function addTaskToWorkflow(input: AddTaskInput): Promise<PendingItem>;
|
|
91
|
+
/** All task-pendings of a workflow, sorted by mandatory order. */
|
|
92
|
+
export declare function workflowTasks(slug: string, code: string, status?: 'open' | 'closed' | 'all'): Promise<PendingItem[]>;
|
|
93
|
+
/** The next task to work: the open task with the lowest order. */
|
|
94
|
+
export declare function nextTask(slug: string, code: string): Promise<PendingItem | undefined>;
|
|
95
|
+
export interface OrderGateResult {
|
|
96
|
+
ok: boolean;
|
|
97
|
+
/** When !ok, the earlier-order open task that blocks this close. */
|
|
98
|
+
blocked_by?: {
|
|
99
|
+
id: string;
|
|
100
|
+
title: string;
|
|
101
|
+
order: number;
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/** Mandatory ordering gate: a task may not close while an EARLIER-order
|
|
105
|
+
* task in the same workflow is still open. Non-workflow items always
|
|
106
|
+
* pass. The caller may override explicitly (force). */
|
|
107
|
+
export declare function canCloseTask(slug: string, id: string): Promise<OrderGateResult>;
|
|
108
|
+
/** After a task closes: if every task of its workflow is now closed,
|
|
109
|
+
* auto-close the instance. Returns the closed instance when it closed. */
|
|
110
|
+
export declare function onWorkflowTaskClosed(slug: string, code: string): Promise<WorkflowInstance | undefined>;
|
|
111
|
+
//# sourceMappingURL=orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/workflow/orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow orchestrator (PND-094 ext) -- DETERMINISTIC, no LLM.
|
|
3
|
+
*
|
|
4
|
+
* Ties the three layers together with plain code:
|
|
5
|
+
* - config.ts -- the editable stage/task definitions (+ DR).
|
|
6
|
+
* - instances.ts -- the running workflow instances (coexisting).
|
|
7
|
+
* - pending store -- the tasks (stages are NOT pendings; tasks are).
|
|
8
|
+
*
|
|
9
|
+
* What this module does, all deterministically:
|
|
10
|
+
* - classify a request (greenfield vs corrective vs evolutive) +
|
|
11
|
+
* flag when confidence is low so the caller ASKS the user.
|
|
12
|
+
* - instantiate a workflow: create the instance + spawn ONE pending
|
|
13
|
+
* per canonical task, in mandatory `order`.
|
|
14
|
+
* - add a task to a running workflow (user OR brain, ad-hoc).
|
|
15
|
+
* - enforce mandatory ordering on close (a task cannot close while an
|
|
16
|
+
* earlier-order task in the same workflow is still open).
|
|
17
|
+
* - auto-close the instance when all its tasks are closed.
|
|
18
|
+
*
|
|
19
|
+
* The LLM is NOT in this loop. It only does the WORK inside each task
|
|
20
|
+
* and (separately) translates NL config-edit requests into a patch.
|
|
21
|
+
*
|
|
22
|
+
* ASCII-only.
|
|
23
|
+
*/
|
|
24
|
+
import { promises as fs } from 'node:fs';
|
|
25
|
+
import { classifyWorkflowKind } from './select.js';
|
|
26
|
+
import { resolveOrderedTasks, seedWorkflowConfigIfMissing } from './config.js';
|
|
27
|
+
import { createInstance, findInstance, findOpenByName, closeInstance, } from './instances.js';
|
|
28
|
+
import { resolveWorkflowDef } from './config.js';
|
|
29
|
+
import { addPending, listPending, } from '../pending/store.js';
|
|
30
|
+
/* ----- project code detection (deterministic heuristic) ----- */
|
|
31
|
+
const CODE_DIR_HINTS = ['src', 'app', 'lib', 'components', 'packages', 'pages'];
|
|
32
|
+
const IGNORE_ENTRIES = new Set(['.forge', '.git', '.github', 'node_modules', 'docs', 'dist', 'build']);
|
|
33
|
+
/** True when the project already has an implementation. Pure fs scan:
|
|
34
|
+
* a package.json / known source dir, or >3 real top-level entries. */
|
|
35
|
+
export async function projectHasCode(projectRoot) {
|
|
36
|
+
try {
|
|
37
|
+
const entries = await fs.readdir(projectRoot, { withFileTypes: true });
|
|
38
|
+
if (entries.some((e) => e.isFile() && e.name === 'package.json'))
|
|
39
|
+
return true;
|
|
40
|
+
if (entries.some((e) => e.isDirectory() && CODE_DIR_HINTS.includes(e.name)))
|
|
41
|
+
return true;
|
|
42
|
+
const real = entries.filter((e) => !e.name.startsWith('.') && !IGNORE_ENTRIES.has(e.name)
|
|
43
|
+
&& !/^readme/i.test(e.name) && !/^license/i.test(e.name));
|
|
44
|
+
return real.length > 3;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const CONFIRM_THRESHOLD = 0.6;
|
|
51
|
+
export async function classifyForProject(projectRoot, requestText) {
|
|
52
|
+
const hasExistingCode = await projectHasCode(projectRoot);
|
|
53
|
+
const r = classifyWorkflowKind({ text: requestText, hasExistingCode });
|
|
54
|
+
return { ...r, needs_confirm: r.confidence < CONFIRM_THRESHOLD };
|
|
55
|
+
}
|
|
56
|
+
/* ----- task <-> pending mapping ----- */
|
|
57
|
+
function taskCategory(gate) {
|
|
58
|
+
/* A gate task needs the owner's explicit OK; everything else Sumi can
|
|
59
|
+
* pick up unsupervised. */
|
|
60
|
+
return gate ? 'user_blocked' : 'autopilot';
|
|
61
|
+
}
|
|
62
|
+
function taskPriority(order) {
|
|
63
|
+
/* Cluster workflow tasks together + keep them in order in the normal
|
|
64
|
+
* pending list (priority asc). */
|
|
65
|
+
return Math.min(100, 20 + order);
|
|
66
|
+
}
|
|
67
|
+
/** Create a workflow instance + spawn one pending per canonical task,
|
|
68
|
+
* in mandatory order. Seeds the editable config (+ DR snapshot) first. */
|
|
69
|
+
export async function instantiateWorkflow(input) {
|
|
70
|
+
await seedWorkflowConfigIfMissing(input.projectRoot);
|
|
71
|
+
const def = await resolveWorkflowDef(input.projectRoot, input.kind);
|
|
72
|
+
const instance = await createInstance(input.slug, {
|
|
73
|
+
kind: input.kind,
|
|
74
|
+
name: input.name,
|
|
75
|
+
stages: def.stages.map((s) => ({ id: s.id, title: s.title })),
|
|
76
|
+
});
|
|
77
|
+
const tasks = await seedCanonicalTasks(input.slug, input.projectRoot, instance);
|
|
78
|
+
return { instance, tasks };
|
|
79
|
+
}
|
|
80
|
+
/** Spawn ONE pending per canonical task of the instance's kind, in
|
|
81
|
+
* mandatory order, linked to the given EXISTING instance. The primitive
|
|
82
|
+
* shared by instantiateWorkflow and by upgrading a backlog-only shell so
|
|
83
|
+
* every phase gets its canonical scaffold (triage/diseno/.../cerrar). */
|
|
84
|
+
export async function seedCanonicalTasks(slug, projectRoot, instance) {
|
|
85
|
+
const orderedTasks = await resolveOrderedTasks(projectRoot, instance.kind);
|
|
86
|
+
const tasks = [];
|
|
87
|
+
for (const t of orderedTasks) {
|
|
88
|
+
const add = {
|
|
89
|
+
title: '[' + instance.code + '] ' + t.title,
|
|
90
|
+
body: t.content,
|
|
91
|
+
category: taskCategory(t.gate),
|
|
92
|
+
priority: taskPriority(t.order),
|
|
93
|
+
workflow: { code: instance.code, kind: instance.kind, stage_id: t.stage_id, order: t.order },
|
|
94
|
+
...(t.gate ? { blocker_kind: 'user_decision', blocker_who: 'pablo' } : {}),
|
|
95
|
+
};
|
|
96
|
+
tasks.push(await addPending(slug, add));
|
|
97
|
+
}
|
|
98
|
+
return tasks;
|
|
99
|
+
}
|
|
100
|
+
/** Create a workflow instance WITHOUT spawning canonical task pendings.
|
|
101
|
+
* Used when the tasks already exist (a backlog folded into a brownfield
|
|
102
|
+
* workflow via attachPendingsToWorkflow). */
|
|
103
|
+
export async function createWorkflowShell(input) {
|
|
104
|
+
await seedWorkflowConfigIfMissing(input.projectRoot);
|
|
105
|
+
const def = await resolveWorkflowDef(input.projectRoot, input.kind);
|
|
106
|
+
return createInstance(input.slug, {
|
|
107
|
+
kind: input.kind,
|
|
108
|
+
name: input.name,
|
|
109
|
+
stages: def.stages.map((s) => ({ id: s.id, title: s.title })),
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
/** Fold EXISTING pendings into a workflow as its tasks, in the given
|
|
113
|
+
* order (default: the order they are passed). Each gets a workflow
|
|
114
|
+
* link with a sequential `order` after any tasks already on the
|
|
115
|
+
* instance. Skips ids that do not exist. Returns the linked items. */
|
|
116
|
+
export async function attachPendingsToWorkflow(input) {
|
|
117
|
+
const inst = await findInstance(input.slug, input.code);
|
|
118
|
+
if (!inst)
|
|
119
|
+
throw new Error('attachPendingsToWorkflow: unknown workflow ' + input.code);
|
|
120
|
+
const existing = await workflowTasks(input.slug, input.code, 'all');
|
|
121
|
+
let order = existing.reduce((m, t) => Math.max(m, t.workflow?.order ?? -1), -1) + 1;
|
|
122
|
+
const stage_id = input.stage_id ?? inst.stages[0]?.id ?? 'stage';
|
|
123
|
+
const { setPendingWorkflow, findPending } = await import('../pending/store.js');
|
|
124
|
+
const out = [];
|
|
125
|
+
for (const id of input.ids) {
|
|
126
|
+
const found = await findPending(input.slug, id);
|
|
127
|
+
if (!found)
|
|
128
|
+
continue;
|
|
129
|
+
/* Attached backlog items are INDEPENDENT (not canonical sequential
|
|
130
|
+
* steps), so they are ad_hoc -> exempt from the ordering gate. */
|
|
131
|
+
const linked = await setPendingWorkflow(input.slug, id, {
|
|
132
|
+
code: inst.code, kind: inst.kind, stage_id, order, ad_hoc: true,
|
|
133
|
+
});
|
|
134
|
+
out.push(linked);
|
|
135
|
+
order += 1;
|
|
136
|
+
}
|
|
137
|
+
return out;
|
|
138
|
+
}
|
|
139
|
+
/** Find an OPEN instance with the same name (same initiative) or create
|
|
140
|
+
* a new one. Coexistence: instances are keyed by code + name, so two
|
|
141
|
+
* distinct initiatives of the same kind run side by side. */
|
|
142
|
+
export async function routeRequest(input) {
|
|
143
|
+
const existing = await findOpenByName(input.slug, input.name);
|
|
144
|
+
if (existing && existing.kind === input.kind)
|
|
145
|
+
return { instance: existing, created: false };
|
|
146
|
+
const { instance } = await instantiateWorkflow(input);
|
|
147
|
+
return { instance, created: true };
|
|
148
|
+
}
|
|
149
|
+
/** On mapping a project, ensure the RIGHT workflow exists -- deterministic,
|
|
150
|
+
* no LLM. greenfield (no code) -> instantiate the build skeleton (tasks
|
|
151
|
+
* spawned). brownfield (has code) -> an evolutive maintenance workflow
|
|
152
|
+
* WITH its canonical tasks per phase (triage/diseno/implementar/validar/
|
|
153
|
+
* docs/cerrar) spawned, so every phase has its canonical scaffold and no
|
|
154
|
+
* phase looks empty; ad-hoc backlog items attach under Implementar.
|
|
155
|
+
* Idempotent: a no-op when the project already has an open workflow, so
|
|
156
|
+
* it is safe to call on every scan/add. Best-effort -- callers must not
|
|
157
|
+
* let it break the map. */
|
|
158
|
+
export async function ensureWorkflowForMappedProject(slug, projectRoot, projectName) {
|
|
159
|
+
const { listInstances } = await import('./instances.js');
|
|
160
|
+
const open = await listInstances(slug, 'open');
|
|
161
|
+
if (open.length > 0) {
|
|
162
|
+
return { created: false, reason: 'ya hay un workflow abierto (' + open[0].code + ')' };
|
|
163
|
+
}
|
|
164
|
+
const label = (projectName && projectName.trim()) || slug;
|
|
165
|
+
const hasCode = await projectHasCode(projectRoot);
|
|
166
|
+
if (hasCode) {
|
|
167
|
+
const { instance } = await instantiateWorkflow({ slug, projectRoot, kind: 'evolutive', name: label + ' -- mantenimiento' });
|
|
168
|
+
return { created: true, kind: 'evolutive', code: instance.code, name: instance.name, reason: 'brownfield (el proyecto ya tiene codigo) -> workflow evolutivo con tareas canonicas por fase' };
|
|
169
|
+
}
|
|
170
|
+
const { instance } = await instantiateWorkflow({ slug, projectRoot, kind: 'greenfield', name: label + ' -- build' });
|
|
171
|
+
return { created: true, kind: 'greenfield', code: instance.code, name: instance.name, reason: 'greenfield (sin codigo) -> skeleton de 18 pasos' };
|
|
172
|
+
}
|
|
173
|
+
/** Append a task to a running workflow at the END of its order. Used
|
|
174
|
+
* for corrective/evolutive tasks the user adds at discretion during a
|
|
175
|
+
* workflow, AND for tasks the brain decides to add mid-execution. */
|
|
176
|
+
export async function addTaskToWorkflow(input) {
|
|
177
|
+
const inst = await findInstance(input.slug, input.code);
|
|
178
|
+
if (!inst)
|
|
179
|
+
throw new Error('addTaskToWorkflow: unknown workflow ' + input.code);
|
|
180
|
+
if (inst.status !== 'open')
|
|
181
|
+
throw new Error('addTaskToWorkflow: workflow ' + input.code + ' is closed');
|
|
182
|
+
const tasks = await workflowTasks(input.slug, input.code, 'all');
|
|
183
|
+
const nextOrder = tasks.reduce((m, t) => Math.max(m, t.workflow?.order ?? 0), -1) + 1;
|
|
184
|
+
const stage_id = input.stage_id ?? inst.stages[inst.stages.length - 1]?.id ?? 'ad-hoc';
|
|
185
|
+
return addPending(input.slug, {
|
|
186
|
+
title: '[' + inst.code + '] ' + input.title,
|
|
187
|
+
...(input.body ? { body: input.body } : {}),
|
|
188
|
+
category: input.category ?? 'autopilot',
|
|
189
|
+
priority: input.priority ?? taskPriority(nextOrder),
|
|
190
|
+
workflow: { code: inst.code, kind: inst.kind, stage_id, order: nextOrder, ad_hoc: true },
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
/* ----- queries + gates ----- */
|
|
194
|
+
/** All task-pendings of a workflow, sorted by mandatory order. */
|
|
195
|
+
export async function workflowTasks(slug, code, status = 'all') {
|
|
196
|
+
const all = await listPending(slug, { status });
|
|
197
|
+
return all
|
|
198
|
+
.filter((p) => p.workflow?.code === code)
|
|
199
|
+
.sort((a, b) => (a.workflow.order - b.workflow.order));
|
|
200
|
+
}
|
|
201
|
+
/** The next task to work: the open task with the lowest order. */
|
|
202
|
+
export async function nextTask(slug, code) {
|
|
203
|
+
const open = await workflowTasks(slug, code, 'open');
|
|
204
|
+
return open[0];
|
|
205
|
+
}
|
|
206
|
+
/** Mandatory ordering gate: a task may not close while an EARLIER-order
|
|
207
|
+
* task in the same workflow is still open. Non-workflow items always
|
|
208
|
+
* pass. The caller may override explicitly (force). */
|
|
209
|
+
export async function canCloseTask(slug, id) {
|
|
210
|
+
const all = await listPending(slug, { status: 'all' });
|
|
211
|
+
const item = all.find((p) => p.id === id);
|
|
212
|
+
if (!item || !item.workflow)
|
|
213
|
+
return { ok: true };
|
|
214
|
+
/* ad_hoc tasks (folded-in backlog items) are INDEPENDENT -- they are
|
|
215
|
+
* never gated, and they never block a canonical step either. The gate
|
|
216
|
+
* applies only among the canonical sequential steps. */
|
|
217
|
+
if (item.workflow.ad_hoc)
|
|
218
|
+
return { ok: true };
|
|
219
|
+
const earlierOpen = all
|
|
220
|
+
.filter((p) => p.workflow?.code === item.workflow.code
|
|
221
|
+
&& p.closed_at === undefined
|
|
222
|
+
&& !p.workflow.ad_hoc
|
|
223
|
+
&& (p.workflow.order < item.workflow.order))
|
|
224
|
+
.sort((a, b) => a.workflow.order - b.workflow.order)[0];
|
|
225
|
+
if (earlierOpen) {
|
|
226
|
+
return { ok: false, blocked_by: { id: earlierOpen.id, title: earlierOpen.title, order: earlierOpen.workflow.order } };
|
|
227
|
+
}
|
|
228
|
+
return { ok: true };
|
|
229
|
+
}
|
|
230
|
+
/** After a task closes: if every task of its workflow is now closed,
|
|
231
|
+
* auto-close the instance. Returns the closed instance when it closed. */
|
|
232
|
+
export async function onWorkflowTaskClosed(slug, code) {
|
|
233
|
+
const open = await workflowTasks(slug, code, 'open');
|
|
234
|
+
if (open.length > 0)
|
|
235
|
+
return undefined;
|
|
236
|
+
const all = await workflowTasks(slug, code, 'all');
|
|
237
|
+
if (all.length === 0)
|
|
238
|
+
return undefined; /* nothing to close on */
|
|
239
|
+
return closeInstance(slug, code);
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/workflow/orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -118,3 +118,35 @@ yujin-design-system/
|
|
|
118
118
|
- **Director**: when the user explicitly requests an override
|
|
119
119
|
("use shadcn"), invokes `yujin.design.override` instead of
|
|
120
120
|
silently accepting. The R8 modal confirms.
|
|
121
|
+
|
|
122
|
+
## Variants -- selectable design systems (PND-112)
|
|
123
|
+
|
|
124
|
+
The Yujin DS ships in two variants. The sumi-e one is the
|
|
125
|
+
DEFAULT; the art deco one is opt-in per product / panel.
|
|
126
|
+
|
|
127
|
+
- **`yujin-design-system`** (default) -- sumi-e aesthetic:
|
|
128
|
+
indigo/teal/amber tones, 170 sumi-e icons, kanji wordmarks.
|
|
129
|
+
- **`yujin-design-system-artdeco`** -- pastel art deco: powder
|
|
130
|
+
blues + warm slate grays + creams + a sparing brass rule,
|
|
131
|
+
Poiret One / Josefin Sans typography, 48 geometric art deco
|
|
132
|
+
icons. NO kanji, NO sumi-e. Crisper geometry (radii 2/4/8).
|
|
133
|
+
|
|
134
|
+
Both expose the SAME semantic token contract (`--color-accent`,
|
|
135
|
+
`--color-bg-*`, `--color-text-*`, `--color-border-*`, state
|
|
136
|
+
colors) and SHARE the same 30 components (theme-agnostic --
|
|
137
|
+
they consume `var(--color-*)`), so picking a variant is purely
|
|
138
|
+
a token + icon swap, never a component rewrite.
|
|
139
|
+
|
|
140
|
+
Selection: the resolver (`src/design/yujin_design_resolver.ts`)
|
|
141
|
+
takes a `ds` selector on every reader (`getManifest({ds})`,
|
|
142
|
+
`getTokensCss({ds})`, `listIcons(tag,{ds})`, `getIconSvg`,
|
|
143
|
+
`listTemplates`, `getTemplate`). `ds: 'artdeco'` -> the pastel
|
|
144
|
+
variant; absent / `'sumie'` / `'default'` -> the sumi-e default.
|
|
145
|
+
`getTokensCss({ds})` returns the theme CSS a generated product
|
|
146
|
+
or the panel injects to apply the look.
|
|
147
|
+
|
|
148
|
+
When a product should use the art deco look (signals: "art
|
|
149
|
+
deco", "pastel", "elegante geometrico", "sin kanjis", "estetica
|
|
150
|
+
clasica/dorada"), select the artdeco variant; otherwise keep the
|
|
151
|
+
sumi-e default. The icon catalog of the SELECTED variant is the
|
|
152
|
+
only one to pull from (no mixing sets).
|
|
@@ -100,3 +100,23 @@ similar. The verbs are cross-platform; no shell needed.
|
|
|
100
100
|
the doc is long.
|
|
101
101
|
- Pair `office.*.write` with R8 modal (policy=approval-required;
|
|
102
102
|
user confirms before disk write).
|
|
103
|
+
|
|
104
|
+
## Opening vs reading (desktop.open vs office.*.read)
|
|
105
|
+
|
|
106
|
+
There are TWO different intents -- pick by what the user wants:
|
|
107
|
+
|
|
108
|
+
- **OPEN / SHOW it to the user** ("abri la planilla", "open this Excel",
|
|
109
|
+
"show me the doc") -> `desktop.open({target})`. It launches the file
|
|
110
|
+
in its native app (.xlsx -> Excel, .docx -> Word, .pdf -> the viewer)
|
|
111
|
+
or, for a Google Sheets/Docs URL or a `.gsheet`/`.gdoc` shortcut, in
|
|
112
|
+
the browser. This is the right move when the human wants to SEE it.
|
|
113
|
+
|
|
114
|
+
- **READ / COMPUTE over the data** ("what's the total", "extract the
|
|
115
|
+
rows", "summarize the doc") -> `office.excel.read` / `office.word.read`
|
|
116
|
+
/ `office.pdf.read`. These return structured data for YOU to reason
|
|
117
|
+
over.
|
|
118
|
+
|
|
119
|
+
NEVER open a binary office file as a pizarron editor tab
|
|
120
|
+
(`forge_open_file_for_editor` / fs.read-file): the bytes render as
|
|
121
|
+
noise and FREEZE the panel (PND-102). The open-file verb now refuses
|
|
122
|
+
office/binary extensions and points here.
|
|
@@ -50,3 +50,43 @@ R7 -- HONEST SEQUENCING (anti-hallucination cont.):
|
|
|
50
50
|
then yujin.git.commit. Three chained invokes. Your chat
|
|
51
51
|
reply summarises the 3 actions AFTER all 3 returned
|
|
52
52
|
result_ok=true.
|
|
53
|
+
|
|
54
|
+
KIND SELECTION (MANDATORY) -- choose the create-tab kind BEFORE
|
|
55
|
+
you invoke. This is a hard rule (invariant level, like R1-R8);
|
|
56
|
+
do NOT improvise. Map the request to a kind by this table:
|
|
57
|
+
|
|
58
|
+
| Request words / intent | kind |
|
|
59
|
+
|-----------------------------------------------------|-------|
|
|
60
|
+
| Flow / flujo / flowchart / proceso / circuito / | bpmn |
|
|
61
|
+
| "los pasos de X" / diagrama de proceso / BPMN | |
|
|
62
|
+
| Relaciones / dependencias / "que usa que" / grafo | graph |
|
|
63
|
+
| del proyecto / nodos sin orden | |
|
|
64
|
+
| Documento / reporte / spec / analisis / diseño / | doc |
|
|
65
|
+
| arquitectura / propuesta / how-to | |
|
|
66
|
+
| Codigo fuente | code |
|
|
67
|
+
| Datos tabulares | table |
|
|
68
|
+
|
|
69
|
+
PROHIBITED: kind="graph" for a process/flow. The graph is for
|
|
70
|
+
relations/dependencies WITHOUT order; a flow has a start, an
|
|
71
|
+
end and ordered steps.
|
|
72
|
+
|
|
73
|
+
Tie-breaker (bpmn vs graph): does the thing have a START and an
|
|
74
|
+
END and ordered STEPS / decisions? -> bpmn. Is it a web of
|
|
75
|
+
relations with no inherent order? -> graph.
|
|
76
|
+
|
|
77
|
+
bpmn content shape (JSON string):
|
|
78
|
+
{"lanes":[{"id","label"}] (optional swimlanes),
|
|
79
|
+
"nodes":[{"id","type","label","lane"?,"gateway"?}],
|
|
80
|
+
"flows":[{"from","to","label"?}]}
|
|
81
|
+
type in startEvent | endEvent | intermediate | task |
|
|
82
|
+
userTask | serviceTask | scriptTask | sendTask |
|
|
83
|
+
receiveTask | gateway
|
|
84
|
+
gateway in exclusive | parallel | inclusive
|
|
85
|
+
|
|
86
|
+
graph content shape (JSON string):
|
|
87
|
+
{"nodes":[{"id","label","weight"?,"kind"?,"detail"?}],
|
|
88
|
+
"edges":[{"from","to","kind"?,"label"?}]}
|
|
89
|
+
|
|
90
|
+
Anti-pattern this prevents (see docs/GOTCHAS.md): rendering a
|
|
91
|
+
business flow with kind="graph". The user asks for a FLUJO and
|
|
92
|
+
gets a force-directed node web instead of a BPMN diagram.
|
|
@@ -59,6 +59,22 @@ In those cases, invoke `yujin.shell.exec` directly. The classifier
|
|
|
59
59
|
will gate destructive / network / elevation commands behind the
|
|
60
60
|
approval modal; safe ones auto-approve.
|
|
61
61
|
|
|
62
|
+
## Long-running commands -> yujin.task.run (MANDATORY)
|
|
63
|
+
|
|
64
|
+
`yujin.shell.exec` runs SYNCHRONOUSLY: it blocks the turn and the
|
|
65
|
+
child process is killed when the turn ends. So a command that does NOT
|
|
66
|
+
terminate on its own -- a dev server, a watcher, `tail -f`, a tunnel
|
|
67
|
+
(`npm/pnpm run dev|start|serve|watch`, `expo start`, `vite`,
|
|
68
|
+
`next dev`, `nodemon`, `wrangler dev`, `docker compose up`,
|
|
69
|
+
`cloudflared tunnel`, ...) -- MUST be launched with `yujin.task.run`,
|
|
70
|
+
which runs it detached so it SURVIVES the turn. Follow it with
|
|
71
|
+
`yujin.task.status` / `yujin.task.list`; the user stops or deletes it
|
|
72
|
+
from the Tareas tab in the pizarron.
|
|
73
|
+
|
|
74
|
+
shell.exec ENFORCES this: it refuses such commands and points you to
|
|
75
|
+
`yujin.task.run` (error `long_running_must_use_task`). Only pass
|
|
76
|
+
`allow_long_running:true` in the rare case you truly need it in-turn.
|
|
77
|
+
|
|
62
78
|
## When to fetch this doctrine
|
|
63
79
|
|
|
64
80
|
Fetch when:
|