@awak-app/simy-cli 0.5.2 → 0.5.3

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 CHANGED
@@ -9,6 +9,14 @@ npm install -g @awak-app/simy-cli
9
9
  simy --daemon
10
10
  ```
11
11
 
12
+ When an interactive `simy --daemon` starts and the managed SIMY workflows are
13
+ missing or outdated, the CLI asks once before installing the Codex plugin
14
+ marketplace, Codex/Claude SQM skills, and PR hooks. Existing unrelated plugins
15
+ and hooks are preserved. Use `--install-workflows` for explicit non-interactive
16
+ installation or `--no-workflow-prompt` to start the daemon without asking.
17
+ After installation, restart Codex and install SIMY from **Plugins → Personal**
18
+ before using `@simy` in a new task.
19
+
12
20
  This is the recommended installation because the CLI can safely install patch
13
21
  and minor releases, and the daemon restarts only when no Agentic Loop task is active. To run
14
22
  the interactive chat after installation, use `simy`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awak-app/simy-cli",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Local SIMY executor for non-coding Local Tasks and Agentic Loop runs.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -38,7 +38,7 @@
38
38
  "test:e2e:console:fullstack": "node ./scripts/fullstack-cli-smoke.js",
39
39
  "check": "npm run check:auto-update && node --check ./src/desktop-executor.js && node --check ./src/local-task.js && node --check ./scripts/desktop-executor-e2e.js && node --check ./scripts/pre-guardrail-e2e.js && node --check ./scripts/fixtures/fake-desktop-provider.js && npm run check:syntax && npm run check:real-provider-syntax && npm test && npm run check:package",
40
40
  "check:auto-update": "node --check ./src/auto-update.js && node --check ./scripts/auto-update-e2e.js && npm run check:sqm",
41
- "check:sqm": "node --check ./src/sqm/canonical.js && node --check ./src/sqm/validation.js && node --check ./src/sqm/reliability.js && node --check ./src/sqm/repository.js && node --check ./src/sqm/checkers.js && node --check ./src/sqm/bundle-store.js && node --check ./src/sqm/proof.js && node --check ./src/sqm/evidence-client.js && node --check ./src/sqm/session.js && node --check ./src/sqm/index.js && node --check ./src/sqm/command.js && node --check ./src/sqm/agent-skill.js && node --check ./src/sqm/review-worker.js && node --check ./scripts/sqm-complete-loop-e2e.js && node --check ./scripts/sqm-local-review-e2e.js",
41
+ "check:sqm": "node --check ./src/sqm/canonical.js && node --check ./src/sqm/validation.js && node --check ./src/sqm/reliability.js && node --check ./src/sqm/repository.js && node --check ./src/sqm/checkers.js && node --check ./src/sqm/bundle-store.js && node --check ./src/sqm/proof.js && node --check ./src/sqm/evidence-client.js && node --check ./src/sqm/session.js && node --check ./src/sqm/index.js && node --check ./src/sqm/command.js && node --check ./src/sqm/agent-skill.js && node --check ./src/sqm/workflow-onboarding.js && node --check ./src/sqm/review-worker.js && node --check ./scripts/sqm-complete-loop-e2e.js && node --check ./scripts/sqm-local-review-e2e.js",
42
42
  "check:real-provider-syntax": "node --check ./scripts/real-codex-probe.js && node --check ./scripts/real-claude-probe.js && node --check ./scripts/real-provider-console-fixture.js && node --check ./scripts/real-provider-console-e2e.js",
43
43
  "check:syntax": "node --check ./src/index.js && node --check ./src/agent.js && node --check ./src/browser.js && node --check ./src/web-api.js && node --check ./src/durable-local-task-worker.js && node --check ./src/durable-local-task-steps-contract.js && node --check ./src/bounded-local-task-subtasks-contract.js && node --check ./src/bounded-local-task-subtask-pool.js && node --check ./src/local-task-artifact-contract.js && node --check ./src/execution-capability-contract.js && node --check ./src/shutdown.js && node --check ./src/run-registry.js && node --check ./src/direct-executor.js && node --check ./src/execution-guardrail.js && node --check ./src/backend-executable.js && node --check ./src/provider-stream.js && node --check ./src/console/index.js && node --check ./src/console/app.js && node --check ./src/console/commands.js && node --check ./src/local-attachments.js && node --check ./src/repository-inventory.js && node --check ./src/session-store.js && node --check ./src/web-origin.js && node --check ./src/workspace-context.js && node --check ./src/orchestrator/index.js && node --check ./src/orchestrator/shared.js && node --check ./src/orchestrator/recovery.js && node --check ./src/orchestrator/risk.js && node --check ./src/orchestrator/contract.js && node --check ./src/orchestrator/completion-contract.js && node --check ./src/orchestrator/instruction.js && node --check ./src/orchestrator/problem-solving.js && node --check ./src/orchestrator/budget.js && node --check ./src/orchestrator/execution-io.js && node --check ./src/orchestrator/presentation.js && node --check ./src/orchestrator/result.js && node --check ./src/orchestrator/retry.js && node --check ./src/orchestrator/evidence.js && node --check ./src/orchestrator/independent-audit.js && node --check ./src/orchestrator/audit.js && node --check ./src/orchestrator/loop.js && node --check ./src/runner.js && node --check ./scripts/fixtures/completion-contract-fixture.js && node --check ./scripts/fixtures/fake-coding-backend.js && node --check ./scripts/e2e-terminal-evidence.js && node --check ./scripts/audit-gate-e2e.js && node --check ./scripts/completion-contract-e2e.js && node --check ./scripts/retry-circuit-e2e.js && node --check ./scripts/follow-up-charter-e2e.js && node --check ./scripts/task-routing-e2e.js && node --check ./scripts/executor-version-preflight-e2e.js && node --check ./scripts/blocked-recovery-e2e.js && node --check ./scripts/process-localization-e2e.js && node --check ./scripts/hypothesis-retries-e2e.js && node --check ./scripts/budget-enforcement-e2e.js && node --check ./scripts/local-task-default-workspace-e2e.js && node --check ./scripts/local-task-idempotency-e2e.js && node --check ./scripts/console-e2e-fixture.js && node --check ./scripts/console-e2e.js && node --check ./scripts/console-recovery-e2e-fixture.js && node --check ./scripts/console-recovery-e2e.js && node --check ./scripts/real-provider-console-fixture.js && node --check ./scripts/real-provider-console-e2e.js && node --check ./scripts/fullstack-cli-smoke.js && node --check ./scripts/check-package-contents.js",
44
44
  "check:package": "node ./scripts/check-package-contents.js"
@@ -13,7 +13,7 @@ import {
13
13
  } from "./durable-local-task-steps-contract.js";
14
14
  import { buildExecutionCapabilityContract } from "./execution-capability-contract.js";
15
15
 
16
- export const CLI_VERSION = "0.5.2";
16
+ export const CLI_VERSION = "0.5.3";
17
17
  export const CLI_API_CONTRACT_VERSION = 10;
18
18
 
19
19
  export function withCliContract(
package/src/index.js CHANGED
@@ -19,6 +19,7 @@ import {
19
19
  createAgentShutdown,
20
20
  installAgentShutdownSignalHandlers,
21
21
  } from "./shutdown.js";
22
+ import { prepareDaemonWorkflows } from "./sqm/workflow-onboarding.js";
22
23
  import { DEFAULT_WEB_ORIGIN, resolveWebOrigin } from "./web-origin.js";
23
24
 
24
25
  const argv = process.argv.slice(2);
@@ -101,6 +102,8 @@ Options:
101
102
  --no-open Do not open the browser when authorization is required
102
103
  --port <port> Bind a specific localhost port
103
104
  --host <url> Connect to a SIMY Web origin (default: ${DEFAULT_WEB_ORIGIN})
105
+ --install-workflows Install or update SIMY Codex/Claude skills and PR hooks
106
+ --no-workflow-prompt Skip the daemon startup workflow-installation prompt
104
107
  --no-auto-update Disable update checks and automatic installation
105
108
 
106
109
  ${autoUpdateHelpText()}
@@ -124,6 +127,14 @@ async function runLocalAgent() {
124
127
  return;
125
128
  }
126
129
 
130
+ try {
131
+ await prepareDaemonWorkflows({ argv, daemon });
132
+ } catch (error) {
133
+ console.error(error instanceof Error ? error.message : String(error));
134
+ process.exitCode = 2;
135
+ return;
136
+ }
137
+
127
138
  if (daemon && process.env.SIMY_DAEMON_CHILD !== "1") {
128
139
  const child = spawn(process.execPath, [fileURLToPath(import.meta.url), ...process.argv.slice(2)], {
129
140
  detached: true,
@@ -0,0 +1,87 @@
1
+ import { createInterface } from "node:readline/promises";
2
+
3
+ import { inspectSqmAgentSkill, installSqmAgentSkill } from "./agent-skill.js";
4
+
5
+ const INSTALL_FLAG = "--install-workflows";
6
+ const SKIP_PROMPT_FLAG = "--no-workflow-prompt";
7
+
8
+ export async function prepareDaemonWorkflows({
9
+ argv,
10
+ daemon,
11
+ daemonChild = process.env.SIMY_DAEMON_CHILD === "1",
12
+ stdinIsTTY = process.stdin.isTTY === true,
13
+ stdoutIsTTY = process.stdout.isTTY === true,
14
+ inspect = inspectSqmAgentSkill,
15
+ install = installSqmAgentSkill,
16
+ confirm = confirmWorkflowInstallation,
17
+ logger = console.log,
18
+ errorLogger = console.error,
19
+ } = {}) {
20
+ if (!daemon || daemonChild) return { outcome: "not_applicable" };
21
+
22
+ const installRequested = argv.includes(INSTALL_FLAG);
23
+ const promptDisabled = argv.includes(SKIP_PROMPT_FLAG);
24
+ if (installRequested && promptDisabled) {
25
+ throw new Error(`${INSTALL_FLAG} cannot be combined with ${SKIP_PROMPT_FLAG}`);
26
+ }
27
+
28
+ let status;
29
+ try {
30
+ status = await inspect();
31
+ } catch (error) {
32
+ errorLogger(
33
+ `SIMY could not inspect the Codex/Claude workflows: ${message(error)}. The daemon will still start.`,
34
+ );
35
+ return { outcome: "inspection_failed", error };
36
+ }
37
+ if (status.installed) return { outcome: "already_installed", status };
38
+ if (promptDisabled) return { outcome: "skipped", status };
39
+
40
+ if (!installRequested && (!stdinIsTTY || !stdoutIsTTY)) {
41
+ logger(
42
+ "SIMY Codex/Claude workflows are missing or outdated. Re-run in a terminal with --install-workflows to install them.",
43
+ );
44
+ return { outcome: "confirmation_unavailable", status };
45
+ }
46
+
47
+ const accepted = installRequested || (await confirm({ status }));
48
+ if (!accepted) {
49
+ logger("SIMY workflow installation skipped. The daemon will still start.");
50
+ return { outcome: "declined", status };
51
+ }
52
+
53
+ try {
54
+ const installed = await install();
55
+ logger(
56
+ "SIMY workflows installed. Restart Codex, then install SIMY from Plugins > Personal before using @simy.",
57
+ );
58
+ return { outcome: "installed", status: installed };
59
+ } catch (error) {
60
+ errorLogger(`SIMY workflow installation failed: ${message(error)}. The daemon will still start.`);
61
+ return { outcome: "installation_failed", error, status };
62
+ }
63
+ }
64
+
65
+ export async function confirmWorkflowInstallation({
66
+ input = process.stdin,
67
+ output = process.stdout,
68
+ } = {}) {
69
+ output.write(
70
+ [
71
+ "SIMY can install or update its Codex plugin marketplace, Codex/Claude SQM skills, and PR hooks.",
72
+ "Existing unrelated plugins and hooks will be preserved.",
73
+ "",
74
+ ].join("\n"),
75
+ );
76
+ const prompt = createInterface({ input, output });
77
+ try {
78
+ const answer = await prompt.question("Install SIMY workflows now? [y/N] ");
79
+ return /^(y|yes)$/i.test(answer.trim());
80
+ } finally {
81
+ prompt.close();
82
+ }
83
+ }
84
+
85
+ function message(error) {
86
+ return error instanceof Error ? error.message : String(error);
87
+ }