@orqint/cli 0.1.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/AGENTS.md ADDED
@@ -0,0 +1,26 @@
1
+ # Agent notes — Orqint
2
+
3
+ ## Cursor-native workflow
4
+
5
+ - **`orqint think prepare "<intent>"`** writes `orqint/.handoff/think.md`. Run the Agent on that file; write the result as **strict JSON** to e.g. `orqint/.handoff/think.response.json`.
6
+ - **`orqint think apply --file <path>`** merges into `orqint/core/memory.json` and applies confidence rules.
7
+ - **`orqint plan prepare`** / **`orqint plan apply --file <path>`** — same pattern for planning.
8
+
9
+ ## Rules
10
+
11
+ - Follow the JSON schema embedded in each handoff.
12
+ - Honor `memory.override` from the sliced context.
13
+ - No OpenAI (or other) API keys in the Orqint CLI; intelligence for `think`/`plan` runs here in Cursor.
14
+
15
+ ## Source of truth
16
+
17
+ - **Canonical:** `orqint/core/memory.json`
18
+ - **Derived:** `orqint-spec/`
19
+
20
+ ## Developing the Orqint CLI (this repository)
21
+
22
+ - TypeScript: `packages/cli/src/`
23
+ - Prompt templates to edit: `packages/cli/prompts/` (built into `dist/orqint/prompts/`)
24
+ - **npm `version`:** bump per [docs/PRD/PRD.md](docs/PRD/PRD.md) §17 before each publish; see `.cursor/rules/orqint-versioning.mdc`.
25
+
26
+ See [docs/Repository-layout.md](docs/Repository-layout.md), [docs/PRD/PRD.md](docs/PRD/PRD.md), and `.cursor/rules/orqint-workflow.mdc`.
package/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # Orqint
2
+
3
+ CLI orchestration for Cursor-native `think` / `plan` workflows. See [docs/PRD/PRD.md](docs/PRD/PRD.md).
4
+
5
+ **Maintainers:** CLI source lives under [`packages/cli/`](packages/cli/README.md). Root folder [`orqint/`](orqint/core/) holds **project state** (`memory.json`, etc.) for this repo only, not TypeScript sources. Full map: [docs/Repository-layout.md](docs/Repository-layout.md).
6
+
7
+ ## Prerequisites
8
+
9
+ - Node.js (LTS)
10
+ - [pnpm](https://pnpm.io/installation) (for developing this repo)
11
+ - [npm](https://www.npmjs.com/) (ships with Node; used by `npx` and `orqint update`)
12
+
13
+ ## Run with `npx` (no global install)
14
+
15
+ After the package is **published to npm** (see below):
16
+
17
+ ```bash
18
+ npx --yes @orqint/cli@latest version
19
+ npx --yes @orqint/cli@latest init
20
+ ```
21
+
22
+ Check for updates (queries the registry):
23
+
24
+ ```bash
25
+ npx --yes @orqint/cli@latest update
26
+ ```
27
+
28
+ Run the latest published CLI via npx (recommended when a newer version exists):
29
+
30
+ ```bash
31
+ npx --yes @orqint/cli@latest <command>
32
+ ```
33
+
34
+ `orqint update --install <args>` re-invokes `npx @orqint/cli@latest <args>` for you when a newer version is available.
35
+
36
+ ### Publish (maintainers)
37
+
38
+ From this repo, with an npm login that can publish to the `@orqint` scope:
39
+
40
+ ```bash
41
+ npm run build
42
+ npm publish
43
+ ```
44
+
45
+ The package is scoped as `@orqint/cli`; `publishConfig.access` is `public` so `npm publish` does not require extra flags.
46
+
47
+ ## Install the `orqint` command (this machine)
48
+
49
+ From the **root of this repository**:
50
+
51
+ ```bash
52
+ pnpm run cli:install
53
+ ```
54
+
55
+ This installs dependencies, builds `dist/`, and runs `pnpm link --global` so `orqint` is on your PATH.
56
+
57
+ On Windows (no `bash`), use:
58
+
59
+ ```bash
60
+ pnpm run cli:install:pnpm
61
+ ```
62
+
63
+ If `orqint` is not found, add pnpm’s global bin directory to your PATH (run `pnpm bin -g` to see it).
64
+
65
+ **Shell alternative (same steps):**
66
+
67
+ ```bash
68
+ bash scripts/setup-cli.sh
69
+ ```
70
+
71
+ ## Update after pulling changes
72
+
73
+ ```bash
74
+ pnpm run cli:upgrade
75
+ ```
76
+
77
+ Or:
78
+
79
+ ```bash
80
+ bash scripts/update-cli.sh
81
+ ```
82
+
83
+ `cli:upgrade` runs `git pull --rebase` (when this folder is a git repo), then reinstalls and rebuilds. Your global link keeps pointing at this folder, so you immediately get the new build.
84
+
85
+ After you `git pull` yourself (or without git), you can run:
86
+
87
+ ```bash
88
+ pnpm run cli:upgrade:pnpm
89
+ ```
90
+
91
+ ## Use in a test project
92
+
93
+ 1. Build / install CLI as above.
94
+ 2. Open an empty folder in Cursor.
95
+ 3. Run `orqint init`, then follow [AGENTS.md](AGENTS.md) and [docs/orqint-cursor-starter.md](docs/orqint-cursor-starter.md).
96
+
97
+ ## Use without global install
98
+
99
+ ```bash
100
+ pnpm run build
101
+ pnpm orqint -- help
102
+ ```
103
+
104
+ Or `node dist/orqint/index.js help` from the repo root.
@@ -0,0 +1,6 @@
1
+ export type InitOptions = {
2
+ force?: boolean;
3
+ brownfield?: boolean;
4
+ migrateLegacy?: boolean;
5
+ };
6
+ export declare function runInit(cwd: string, opts: InitOptions): Promise<void>;
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.runInit = runInit;
37
+ const path = __importStar(require("path"));
38
+ const fs = __importStar(require("fs-extra"));
39
+ const paths_1 = require("../engine/paths");
40
+ const memory_1 = require("../utils/memory");
41
+ const logger_1 = require("../utils/logger");
42
+ async function runInit(cwd, opts) {
43
+ const root = (0, paths_1.orqintRoot)(cwd);
44
+ const memPath = (0, paths_1.memoryJsonPath)(cwd);
45
+ const exists = await fs.pathExists(memPath);
46
+ if (exists && !opts.force) {
47
+ throw new Error(`memory already exists at ${memPath}. Use --force to re-initialize template.`);
48
+ }
49
+ await fs.ensureDir(path.join(root, "core"));
50
+ await fs.ensureDir(path.join(root, "prompts"));
51
+ const bundledPrompts = path.join(__dirname, "../prompts");
52
+ const targetPrompts = path.join(root, "prompts");
53
+ if (await fs.pathExists(bundledPrompts)) {
54
+ await fs.copy(bundledPrompts, targetPrompts, { overwrite: false });
55
+ }
56
+ await fs.ensureDir(path.join(root, "commands"));
57
+ await fs.ensureDir(path.join(root, "engine"));
58
+ await fs.ensureDir(path.join(root, "utils"));
59
+ await fs.ensureDir(path.join(root, ".handoff"));
60
+ await fs.ensureDir((0, paths_1.orqintSpecDir)(cwd));
61
+ await fs.ensureDir((0, paths_1.orqintArchiveDir)(cwd));
62
+ let memory = (0, memory_1.ensureDefaults)(JSON.parse(JSON.stringify(memory_1.EMPTY_MEMORY)));
63
+ if (opts.brownfield) {
64
+ memory = await seedFromRepo(cwd, memory);
65
+ }
66
+ if (opts.migrateLegacy) {
67
+ await migrateLegacyFolder(cwd);
68
+ }
69
+ (0, memory_1.validateFoundation)(memory);
70
+ await (0, memory_1.writeMemory)(cwd, memory);
71
+ (0, logger_1.log)("info", "init_complete", { cwd, brownfield: !!opts.brownfield });
72
+ }
73
+ async function seedFromRepo(cwd, memory) {
74
+ const pkgPath = path.join(cwd, "package.json");
75
+ if (await fs.pathExists(pkgPath)) {
76
+ try {
77
+ const pkg = (await fs.readJson(pkgPath));
78
+ if (pkg.name && !memory.project.name) {
79
+ memory.project = { ...memory.project, name: pkg.name };
80
+ }
81
+ if (!memory.project.type) {
82
+ memory.project.type = inferProjectType(pkg);
83
+ }
84
+ memory.tech_stack = {
85
+ ...memory.tech_stack,
86
+ ...(pkg.dependencies ? { dependencies: pkg.dependencies } : {}),
87
+ ...(pkg.devDependencies
88
+ ? { devDependencies: pkg.devDependencies }
89
+ : {}),
90
+ };
91
+ }
92
+ catch {
93
+ (0, logger_1.log)("warn", "init_brownfield_package_read_failed", { path: pkgPath });
94
+ }
95
+ }
96
+ const readme = path.join(cwd, "README.md");
97
+ if ((await fs.pathExists(readme)) && memory.goals.length === 0) {
98
+ const snippet = (await fs.readFile(readme, "utf8")).slice(0, 400);
99
+ if (snippet.trim()) {
100
+ const line = snippet.split("\n")[0]?.slice(0, 200) ?? "See README.md";
101
+ memory.goals = [`(from README) ${line}`];
102
+ }
103
+ }
104
+ return (0, memory_1.ensureDefaults)(memory);
105
+ }
106
+ function inferProjectType(pkg) {
107
+ const all = {
108
+ ...pkg.dependencies,
109
+ ...pkg.devDependencies,
110
+ };
111
+ if (all["next"]) {
112
+ return "nextjs";
113
+ }
114
+ if (all["react"]) {
115
+ return "react";
116
+ }
117
+ if (all["express"]) {
118
+ return "node";
119
+ }
120
+ return "unknown";
121
+ }
122
+ async function migrateLegacyFolder(cwd) {
123
+ const legacy = path.join(cwd, "legacy");
124
+ if (!(await fs.pathExists(legacy))) {
125
+ (0, logger_1.log)("info", "migrate_legacy_skip", { reason: "no ./legacy directory" });
126
+ return;
127
+ }
128
+ const stamp = new Date().toISOString().replace(/[:.]/g, "-");
129
+ const dest = path.join((0, paths_1.orqintArchiveDir)(cwd), `legacy-${stamp}`);
130
+ await fs.ensureDir((0, paths_1.orqintArchiveDir)(cwd));
131
+ await fs.move(legacy, dest);
132
+ (0, logger_1.log)("info", "legacy_migrated", { from: legacy, to: dest });
133
+ }
@@ -0,0 +1,7 @@
1
+ export declare function planPrepare(cwd: string): Promise<{
2
+ handoffPath: string;
3
+ }>;
4
+ export declare function planPrepareAllowLowConfidence(cwd: string): Promise<{
5
+ handoffPath: string;
6
+ }>;
7
+ export declare function planApply(cwd: string, responseFile: string, force: boolean): Promise<void>;
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.planPrepare = planPrepare;
37
+ exports.planPrepareAllowLowConfidence = planPrepareAllowLowConfidence;
38
+ exports.planApply = planApply;
39
+ const fs = __importStar(require("fs-extra"));
40
+ const path = __importStar(require("path"));
41
+ const context_1 = require("../engine/context");
42
+ const handoff_1 = require("../engine/handoff");
43
+ const memory_1 = require("../utils/memory");
44
+ const parser_1 = require("../utils/parser");
45
+ const confidence_1 = require("../engine/confidence");
46
+ const paths_1 = require("../engine/paths");
47
+ const logger_1 = require("../utils/logger");
48
+ async function planPrepare(cwd) {
49
+ const memory = await (0, memory_1.readMemory)(cwd);
50
+ if (!(0, confidence_1.canStartPlan)(memory.confidence, false)) {
51
+ throw new Error(`confidence ${memory.confidence} < ${confidence_1.CONFIDENCE_BLOCK}: run think apply first or use plan prepare --force (not recommended)`);
52
+ }
53
+ const slice = (0, context_1.sliceForPlan)(memory);
54
+ const handoffPath = await (0, handoff_1.writePlanHandoff)(cwd, slice);
55
+ (0, logger_1.log)("info", "plan_prepare_done", { handoffPath });
56
+ return { handoffPath };
57
+ }
58
+ async function planPrepareAllowLowConfidence(cwd) {
59
+ const memory = await (0, memory_1.readMemory)(cwd);
60
+ const slice = (0, context_1.sliceForPlan)(memory);
61
+ const handoffPath = await (0, handoff_1.writePlanHandoff)(cwd, slice);
62
+ (0, logger_1.log)("warn", "plan_prepare_forced_low_confidence", {
63
+ confidence: memory.confidence,
64
+ });
65
+ return { handoffPath };
66
+ }
67
+ async function planApply(cwd, responseFile, force) {
68
+ const memory = await (0, memory_1.readMemory)(cwd);
69
+ if (!(0, confidence_1.canStartPlan)(memory.confidence, force)) {
70
+ throw new Error(`confidence ${memory.confidence} < ${confidence_1.CONFIDENCE_BLOCK}: run think apply or pass --force`);
71
+ }
72
+ const rawText = await fs.readFile(responseFile, "utf8");
73
+ const parsed = (0, parser_1.parseJsonFromText)(rawText);
74
+ const payload = validatePlanPayload(parsed);
75
+ const next = mergePlanIntoMemory(memory, payload);
76
+ await (0, memory_1.writeMemory)(cwd, next);
77
+ await writePlanSpec(cwd, next);
78
+ (0, logger_1.log)("info", "plan_apply_done", { responseFile });
79
+ }
80
+ function validatePlanPayload(parsed) {
81
+ for (const key of ["features", "flows", "pages", "states"]) {
82
+ if (!Array.isArray(parsed[key])) {
83
+ throw new Error(`plan response: missing array \`${key}\``);
84
+ }
85
+ }
86
+ return parsed;
87
+ }
88
+ function mergePlanIntoMemory(memory, p) {
89
+ const edge = Array.isArray(p.edge_cases) && p.edge_cases.every((e) => typeof e === "string")
90
+ ? p.edge_cases
91
+ : memory.edge_cases;
92
+ return {
93
+ ...memory,
94
+ features: p.features ?? memory.features,
95
+ flows: p.flows ?? memory.flows,
96
+ pages: p.pages ?? memory.pages,
97
+ states: p.states ?? memory.states,
98
+ edge_cases: edge,
99
+ };
100
+ }
101
+ async function writePlanSpec(cwd, memory) {
102
+ const dir = (0, paths_1.orqintSpecDir)(cwd);
103
+ await fs.ensureDir(dir);
104
+ const summary = path.join(dir, "plan-summary.md");
105
+ const body = `# Plan summary (derived — do not treat as source of truth)
106
+
107
+ Canonical state remains \`orqint/core/memory.json\`.
108
+
109
+ ## Features
110
+
111
+ \`\`\`json
112
+ ${JSON.stringify(memory.features, null, 2)}
113
+ \`\`\`
114
+
115
+ ## Flows
116
+
117
+ \`\`\`json
118
+ ${JSON.stringify(memory.flows, null, 2)}
119
+ \`\`\`
120
+
121
+ ## Pages
122
+
123
+ \`\`\`json
124
+ ${JSON.stringify(memory.pages, null, 2)}
125
+ \`\`\`
126
+
127
+ ## States
128
+
129
+ \`\`\`json
130
+ ${JSON.stringify(memory.states, null, 2)}
131
+ \`\`\`
132
+
133
+ ## Edge cases
134
+
135
+ ${memory.edge_cases.map((e) => `- ${e}`).join("\n") || "(none)"}
136
+ `;
137
+ await fs.writeFile(summary, body, "utf8");
138
+ }
@@ -0,0 +1,8 @@
1
+ export declare function thinkPrepare(cwd: string, userIntent: string, overrides: Record<string, boolean | string>): Promise<{
2
+ handoffPath: string;
3
+ stdout?: string;
4
+ }>;
5
+ export declare function thinkApply(cwd: string, responseFile: string): Promise<{
6
+ exitCode: number;
7
+ messages: string[];
8
+ }>;
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.thinkPrepare = thinkPrepare;
37
+ exports.thinkApply = thinkApply;
38
+ const fs = __importStar(require("fs-extra"));
39
+ const context_1 = require("../engine/context");
40
+ const handoff_1 = require("../engine/handoff");
41
+ const memory_1 = require("../utils/memory");
42
+ const parser_1 = require("../utils/parser");
43
+ const confidence_1 = require("../engine/confidence");
44
+ const logger_1 = require("../utils/logger");
45
+ async function thinkPrepare(cwd, userIntent, overrides) {
46
+ let memory = await (0, memory_1.readMemory)(cwd);
47
+ if (Object.keys(overrides).length > 0) {
48
+ memory = {
49
+ ...memory,
50
+ override: { ...memory.override, ...overrides },
51
+ };
52
+ await (0, memory_1.writeMemory)(cwd, memory);
53
+ }
54
+ const slice = (0, context_1.sliceForThink)(memory, userIntent);
55
+ const handoffPath = await (0, handoff_1.writeThinkHandoff)(cwd, userIntent, slice);
56
+ (0, logger_1.log)("info", "think_prepare_done", { handoffPath });
57
+ return { handoffPath };
58
+ }
59
+ async function thinkApply(cwd, responseFile) {
60
+ const rawText = await fs.readFile(responseFile, "utf8");
61
+ const parsed = (0, parser_1.parseJsonFromText)(rawText);
62
+ const payload = validateThinkPayload(parsed);
63
+ let memory = await (0, memory_1.readMemory)(cwd);
64
+ memory = mergeThinkIntoMemory(memory, payload);
65
+ await (0, memory_1.writeMemory)(cwd, memory);
66
+ const outcome = (0, confidence_1.evaluateAfterThink)(payload.confidence);
67
+ const messages = [
68
+ `Memory updated from ${responseFile}`,
69
+ ...outcome.messages,
70
+ ];
71
+ if (memory.open_questions.length > 0 && payload.confidence < 0.8) {
72
+ messages.push("Open questions:\n- " + memory.open_questions.join("\n- "));
73
+ }
74
+ (0, logger_1.log)("info", "think_apply_done", {
75
+ confidence: payload.confidence,
76
+ exitCode: outcome.exitCode,
77
+ });
78
+ return { exitCode: outcome.exitCode, messages };
79
+ }
80
+ function validateThinkPayload(parsed) {
81
+ if (typeof parsed.confidence !== "number" || Number.isNaN(parsed.confidence)) {
82
+ throw new Error("think response: missing or invalid numeric `confidence`");
83
+ }
84
+ const oq = parsed.open_questions;
85
+ if (!Array.isArray(oq)) {
86
+ throw new Error("think response: `open_questions` must be an array");
87
+ }
88
+ const questions = oq.filter((x) => typeof x === "string");
89
+ if (questions.length > 5) {
90
+ throw new Error("think response: at most 5 open_questions allowed");
91
+ }
92
+ return {
93
+ ...parsed,
94
+ confidence: parsed.confidence,
95
+ open_questions: questions,
96
+ };
97
+ }
98
+ function mergeThinkIntoMemory(memory, p) {
99
+ const project = { ...memory.project };
100
+ if (p.project && typeof p.project === "object") {
101
+ const pr = p.project;
102
+ if (typeof pr.name === "string") {
103
+ project.name = pr.name;
104
+ }
105
+ if (typeof pr.type === "string") {
106
+ project.type = pr.type;
107
+ }
108
+ if (typeof pr.description === "string") {
109
+ project.description = pr.description;
110
+ }
111
+ }
112
+ if (typeof p.project_type === "string" && p.project_type.trim()) {
113
+ if (!project.type) {
114
+ project.type = p.project_type.trim();
115
+ }
116
+ }
117
+ const goals = Array.isArray(p.goals) && p.goals.every((g) => typeof g === "string")
118
+ ? p.goals
119
+ : memory.goals;
120
+ const open_questions = p.open_questions ?? memory.open_questions;
121
+ const unknowns = Array.isArray(p.unknowns)
122
+ ? p.unknowns.filter((u) => typeof u === "string")
123
+ : memory.unknowns;
124
+ const requires_input = typeof p.requires_input === "boolean"
125
+ ? p.requires_input
126
+ : memory.requires_input;
127
+ let tech_stack = memory.tech_stack;
128
+ if (p.tech_stack && typeof p.tech_stack === "object") {
129
+ tech_stack = (0, memory_1.deepMergeTechStack)(memory.tech_stack, p.tech_stack);
130
+ }
131
+ return {
132
+ ...memory,
133
+ project,
134
+ goals,
135
+ open_questions,
136
+ confidence: p.confidence,
137
+ unknowns,
138
+ requires_input,
139
+ tech_stack,
140
+ };
141
+ }
@@ -0,0 +1,5 @@
1
+ import type { PackageMeta } from "../package-meta";
2
+ /**
3
+ * Check npm registry for a newer version; optionally re-invoke via npx @latest.
4
+ */
5
+ export declare function runUpdate(meta: PackageMeta, install: boolean, forwardArgs: string[]): void;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runUpdate = runUpdate;
4
+ const child_process_1 = require("child_process");
5
+ function compareSemver(a, b) {
6
+ const pa = a.split(/[.+]/).map((x) => parseInt(x, 10) || 0);
7
+ const pb = b.split(/[.+]/).map((x) => parseInt(x, 10) || 0);
8
+ const n = Math.max(pa.length, pb.length);
9
+ for (let i = 0; i < n; i++) {
10
+ const da = pa[i] ?? 0;
11
+ const db = pb[i] ?? 0;
12
+ if (da < db) {
13
+ return -1;
14
+ }
15
+ if (da > db) {
16
+ return 1;
17
+ }
18
+ }
19
+ return 0;
20
+ }
21
+ function fetchLatestFromNpm(name) {
22
+ try {
23
+ const out = (0, child_process_1.execFileSync)("npm", ["view", name, "version"], {
24
+ encoding: "utf8",
25
+ timeout: 20_000,
26
+ stdio: ["ignore", "pipe", "pipe"],
27
+ }).trim();
28
+ return out || null;
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ }
34
+ /**
35
+ * Check npm registry for a newer version; optionally re-invoke via npx @latest.
36
+ */
37
+ function runUpdate(meta, install, forwardArgs) {
38
+ const latest = fetchLatestFromNpm(meta.name);
39
+ if (!latest) {
40
+ console.error(`Could not read latest version from npm for "${meta.name}".`);
41
+ console.error("The package may be unpublished, or npm/registry is unreachable.");
42
+ console.error(`This CLI build: ${meta.name}@${meta.version}`);
43
+ if (install) {
44
+ process.exit(1);
45
+ }
46
+ process.exit(0);
47
+ }
48
+ const newer = compareSemver(latest, meta.version) > 0;
49
+ if (!newer) {
50
+ console.error(`orqint is up to date (${meta.version}).`);
51
+ process.exit(0);
52
+ }
53
+ console.error(`Current: ${meta.version}`);
54
+ console.error(`Latest: ${latest}`);
55
+ console.error("");
56
+ console.error(`Use a fresh run with npx:`);
57
+ console.error(` npx --yes ${meta.name}@latest <command>`);
58
+ console.error("");
59
+ if (install) {
60
+ const r = (0, child_process_1.spawnSync)("npx", ["--yes", `${meta.name}@latest`, ...forwardArgs], { stdio: "inherit", shell: process.platform === "win32" });
61
+ process.exit(r.status === null ? 1 : r.status);
62
+ }
63
+ process.exit(0);
64
+ }
@@ -0,0 +1,10 @@
1
+ /** CGR-005 thresholds (tunable). */
2
+ export declare const CONFIDENCE_BLOCK = 0.6;
3
+ export declare const CONFIDENCE_ASK = 0.8;
4
+ export declare const CONFIDENCE_PROCEED = 0.9;
5
+ export type ConfidenceOutcome = {
6
+ exitCode: number;
7
+ messages: string[];
8
+ };
9
+ export declare function evaluateAfterThink(confidence: number): ConfidenceOutcome;
10
+ export declare function canStartPlan(confidence: number, force: boolean): boolean;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CONFIDENCE_PROCEED = exports.CONFIDENCE_ASK = exports.CONFIDENCE_BLOCK = void 0;
4
+ exports.evaluateAfterThink = evaluateAfterThink;
5
+ exports.canStartPlan = canStartPlan;
6
+ /** CGR-005 thresholds (tunable). */
7
+ exports.CONFIDENCE_BLOCK = 0.6;
8
+ exports.CONFIDENCE_ASK = 0.8;
9
+ exports.CONFIDENCE_PROCEED = 0.9;
10
+ function evaluateAfterThink(confidence) {
11
+ const messages = [];
12
+ if (confidence < exports.CONFIDENCE_BLOCK) {
13
+ messages.push(`[CGR-005] confidence ${confidence} < ${exports.CONFIDENCE_BLOCK}: blocked for planning until you raise confidence (answer open_questions and re-run think apply).`);
14
+ return { exitCode: 2, messages };
15
+ }
16
+ if (confidence < exports.CONFIDENCE_ASK) {
17
+ messages.push(`[CGR-005] confidence ${confidence} < ${exports.CONFIDENCE_ASK}: review open_questions before planning.`);
18
+ }
19
+ if (confidence >= exports.CONFIDENCE_PROCEED) {
20
+ messages.push(`[CGR-005] confidence ${confidence} >= ${exports.CONFIDENCE_PROCEED}: ready to run plan prepare.`);
21
+ }
22
+ return { exitCode: 0, messages };
23
+ }
24
+ function canStartPlan(confidence, force) {
25
+ if (force) {
26
+ return true;
27
+ }
28
+ return confidence >= exports.CONFIDENCE_BLOCK;
29
+ }