@logicseek/hello-cc 1.0.5 → 1.1.0-rc.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/CHANGELOG.md +72 -0
- package/docs/codex-account.zh-CN.md +38 -0
- package/docs/codex-protocol.md +59 -0
- package/docs/commands.md +9 -0
- package/docs/commands.zh-CN.md +7 -0
- package/docs/macos-process-identity.md +2 -0
- package/docs/native.md +179 -14
- package/docs/native.zh-CN.md +136 -6
- package/docs/web-handoff.zh-CN.md +118 -8
- package/lib/cli/app.mjs +47 -4
- package/lib/cli/commands/coordination.mjs +14 -4
- package/lib/cli/commands/dsh.mjs +1 -1
- package/lib/cli/commands/gc.mjs +22 -15
- package/lib/cli/commands/hook.mjs +19 -3
- package/lib/cli/commands/install.mjs +80 -10
- package/lib/cli/commands/misc.mjs +36 -9
- package/lib/cli/commands/native.mjs +4 -38
- package/lib/cli/commands/peer.mjs +3 -0
- package/lib/cli/commands/run.mjs +13 -6
- package/lib/cli/commands/tmux.mjs +1 -2
- package/lib/cli-runtime.mjs +19 -2
- package/lib/core/coordination/results.mjs +27 -10
- package/lib/core/sessions/hook-root-identity.mjs +47 -0
- package/lib/core/sessions/launch.mjs +7 -1
- package/lib/db/connection.mjs +140 -42
- package/lib/db/schema.mjs +59 -0
- package/lib/diagnostics/codex-protocol.mjs +105 -0
- package/lib/guidance.mjs +21 -36
- package/lib/integrations/codex-account.mjs +143 -0
- package/lib/integrations/codex-interactions.mjs +13 -11
- package/lib/integrations/dsh-collaboration.mjs +6 -12
- package/lib/integrations/dsh-cordis.mjs +17 -13
- package/lib/integrations/dsh.mjs +16 -11
- package/lib/integrations/mcp-elicitation.mjs +116 -0
- package/lib/integrations/mcp-url-elicitation.mjs +25 -0
- package/lib/integrations/native/claude.mjs +24 -6
- package/lib/integrations/native/codex.mjs +38 -7
- package/lib/integrations/native/dsh-acp.mjs +67 -24
- package/lib/integrations/native/index.mjs +4 -1
- package/lib/integrations/native/interactions.mjs +2 -1
- package/lib/integrations/native/jsonrpc.mjs +37 -5
- package/lib/integrations/native/telemetry.mjs +30 -0
- package/lib/process/identity.mjs +4 -0
- package/lib/process/pinned-cwd.mjs +302 -0
- package/lib/process/pinned-guidance.mjs +138 -0
- package/lib/process/pinned-project-state.mjs +105 -0
- package/lib/process/selected-cwd-identity.mjs +95 -0
- package/lib/runtime/buffer-evidence.mjs +2 -1
- package/lib/runtime/client.mjs +9 -0
- package/lib/runtime/native/client.mjs +4 -1
- package/lib/runtime/native/history.mjs +140 -0
- package/lib/runtime/native/launcher.mjs +106 -0
- package/lib/runtime/native/service.mjs +64 -8
- package/lib/runtime/native/store.mjs +83 -58
- package/lib/runtime/paths.mjs +17 -2
- package/lib/runtime/private-file.mjs +76 -0
- package/lib/runtime/private-state.mjs +546 -0
- package/lib/runtime/project-context.mjs +2 -1
- package/lib/runtime/project-path.mjs +92 -20
- package/lib/runtime/project-trust.mjs +79 -0
- package/lib/runtime/projects.mjs +9 -3
- package/lib/runtime/state-migration.mjs +697 -0
- package/lib/runtime/state.mjs +69 -27
- package/lib/shared/automatic-result-key.mjs +6 -0
- package/lib/shared/json-file.mjs +55 -6
- package/lib/shared/redact.mjs +2 -1
- package/lib/ui/help.mjs +6 -4
- package/lib/web/agent-defaults.mjs +110 -0
- package/lib/web/auto-attach.mjs +3 -2
- package/lib/web/browser/contracts.d.ts +10 -0
- package/lib/web/browser/core.mjs +1997 -0
- package/lib/web/browser/project-data.mjs +158 -0
- package/lib/web/browser/session-sync.mjs +82 -0
- package/lib/web/browser-assets.mjs +19 -0
- package/lib/web/buffer-gc-runtime.mjs +2 -2
- package/lib/web/codex-app-server.mjs +111 -37
- package/lib/web/codex-sessions.mjs +61 -12
- package/lib/web/context-files.mjs +82 -0
- package/lib/web/cookie-auth.mjs +51 -3
- package/lib/web/external-sessions.mjs +76 -9
- package/lib/web/http-routes.mjs +238 -25
- package/lib/web/http.mjs +50 -4
- package/lib/web/liveness-reaper.mjs +2 -2
- package/lib/web/native-sessions.mjs +323 -14
- package/lib/web/project-contexts.mjs +236 -44
- package/lib/web/project-file-write.mjs +249 -0
- package/lib/web/project-files.mjs +268 -0
- package/lib/web/pty-sessions.mjs +11 -3
- package/lib/web/runtime-main.mjs +132 -80
- package/lib/web/session-serialize.mjs +87 -8
- package/lib/web/session-state-sync.mjs +98 -0
- package/lib/web/shutdown-diagnostics.mjs +38 -0
- package/lib/web/shutdown-response.mjs +21 -0
- package/lib/web/shutdown-state.mjs +91 -0
- package/lib/web/startup.mjs +103 -35
- package/lib/web/task-results.mjs +19 -19
- package/lib/web/tls.mjs +84 -33
- package/lib/web/tmux-sessions.mjs +73 -9
- package/lib/web/tmux-stream.mjs +36 -8
- package/lib/web/ui-agent-defaults.mjs +149 -0
- package/lib/web/ui-agent-start.mjs +330 -0
- package/lib/web/ui-codex-account.mjs +81 -0
- package/lib/web/ui-codex.mjs +105 -85
- package/lib/web/ui-command-palette.mjs +21 -5
- package/lib/web/ui-file-writes.mjs +220 -0
- package/lib/web/ui-files.mjs +231 -0
- package/lib/web/ui-handoff.mjs +10 -2
- package/lib/web/ui-history.mjs +175 -105
- package/lib/web/ui-i18n.mjs +280 -8
- package/lib/web/ui-interactions.mjs +107 -6
- package/lib/web/ui-native-timeline.mjs +326 -0
- package/lib/web/ui-native.mjs +93 -43
- package/lib/web/ui-review.mjs +5 -3
- package/lib/web/ui-safe-markdown.mjs +79 -0
- package/lib/web/ui-session-tools.mjs +224 -0
- package/lib/web/ui-template.mjs +29 -1968
- package/lib/web/ui-terminal-find.mjs +5 -3
- package/lib/web/ui-workbench.mjs +5 -3
- package/lib/web/ui-workspace.mjs +3 -0
- package/package.json +8 -2
- package/scripts/benchmark-session-sync.mjs +53 -0
- package/scripts/codex-protocol.mjs +88 -0
- package/scripts/dsh-approval-layers-acceptance.mjs +172 -0
- package/scripts/dsh-package-provenance.mjs +118 -0
- package/scripts/mcp-form-live-fixture.mjs +81 -0
- package/scripts/native-bounded-live-acceptance.mjs +193 -0
- package/scripts/native-fixture-root.mjs +49 -0
- package/scripts/native-installed-acceptance.mjs +611 -0
- package/scripts/native-stability-checks.mjs +40 -0
- package/scripts/regression-cookie-expiry.mjs +70 -0
- package/scripts/regression-http-transport.mjs +9 -0
- package/scripts/regression-terminal-marker.mjs +95 -0
- package/scripts/regression.mjs +481 -219
- package/scripts/shim-reentry-probe.mjs +105 -0
- package/scripts/web-acceptance-diagnostics.mjs +90 -0
- package/scripts/web-codex-account-acceptance.mjs +178 -0
- package/scripts/web-file-preview-checks.mjs +302 -0
- package/scripts/web-mcp-form-acceptance.mjs +134 -0
- package/scripts/web-mcp-form-live-acceptance.mjs +368 -0
- package/scripts/web-native-handoff-checks.mjs +128 -0
- package/scripts/web-native-interaction-acceptance.mjs +219 -18
- package/scripts/web-native-interaction-diagnostics.mjs +80 -0
- package/scripts/web-native-model-acceptance.mjs +22 -7
- package/scripts/web-session-tools-checks.mjs +112 -0
- package/scripts/web-workbench-acceptance.mjs +435 -0
- package/scripts/web-workbench-installed-acceptance.mjs +122 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// Pack and install a local candidate, then run its public CLI and browser fixture.
|
|
2
|
+
// No model, real account, global installation or publication is involved.
|
|
3
|
+
import assert from 'node:assert/strict';
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import os from 'node:os';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { createHash } from 'node:crypto';
|
|
8
|
+
import { spawnSync } from 'node:child_process';
|
|
9
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
10
|
+
import { FILE_PREVIEW_CHECKS } from './web-file-preview-checks.mjs';
|
|
11
|
+
|
|
12
|
+
const args = process.argv.slice(2);
|
|
13
|
+
if (args.includes('--help')) {
|
|
14
|
+
console.log('Usage: node scripts/web-workbench-installed-acceptance.mjs [--output-dir DIR] [--output FILE]');
|
|
15
|
+
console.log('Packs this checkout, installs into a disposable prefix, and runs its model-free browser acceptance. Requires Node 24+, npm, tmux and Playwright Chromium.');
|
|
16
|
+
process.exit(0);
|
|
17
|
+
}
|
|
18
|
+
const options = new Map();
|
|
19
|
+
for (let index = 0; index < args.length; index += 2) {
|
|
20
|
+
if (!['--output-dir', '--output'].includes(args[index]) || !args[index + 1] || args[index + 1].startsWith('--')) throw new Error('Unknown or incomplete option: ' + args[index]);
|
|
21
|
+
options.set(args[index], args[index + 1]);
|
|
22
|
+
}
|
|
23
|
+
assert.ok(Number(process.versions.node.split('.')[0]) >= 24, 'Installed acceptance requires Node 24+');
|
|
24
|
+
assert.notEqual(process.platform, 'win32', 'Run this tmux-based acceptance under WSL on Windows');
|
|
25
|
+
const repo = fileURLToPath(new URL('..', import.meta.url));
|
|
26
|
+
const dir = path.resolve(options.get('--output-dir') || fs.mkdtempSync(path.join(os.tmpdir(), 'hcc-workbench-installed-evidence-')));
|
|
27
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
28
|
+
const output = path.resolve(options.get('--output') || path.join(dir, 'evidence.json'));
|
|
29
|
+
const sandbox = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'hcc-workbench-install-')));
|
|
30
|
+
const prefix = path.join(sandbox, 'install'), taskHome = path.join(sandbox, 'home');
|
|
31
|
+
fs.mkdirSync(prefix, { recursive: true }); fs.mkdirSync(taskHome, { recursive: true, mode: 0o700 });
|
|
32
|
+
fs.writeFileSync(path.join(prefix, 'package.json'), JSON.stringify({ name: 'hcc-browser-install-fixture', version: '0.0.0', private: true }));
|
|
33
|
+
fs.writeFileSync(path.join(taskHome, '.npmrc'), '');
|
|
34
|
+
fs.writeFileSync(path.join(taskHome, 'global-npmrc'), '');
|
|
35
|
+
const env = {
|
|
36
|
+
PATH: [path.dirname(process.execPath), process.env.PATH || '/usr/bin:/bin'].join(path.delimiter),
|
|
37
|
+
HOME: taskHome, TMPDIR: sandbox, LANG: 'C.UTF-8', SHELL: '/bin/sh',
|
|
38
|
+
NPM_CONFIG_CACHE: path.join(sandbox, 'npm-cache'), NPM_CONFIG_USERCONFIG: path.join(taskHome, '.npmrc'),
|
|
39
|
+
NPM_CONFIG_GLOBALCONFIG: path.join(taskHome, 'global-npmrc'),
|
|
40
|
+
NPM_CONFIG_REGISTRY: 'https://registry.npmjs.org',
|
|
41
|
+
HCC_NO_AUTO_INSTALL_TMUX: '1'
|
|
42
|
+
};
|
|
43
|
+
const sha256 = filename => createHash('sha256').update(fs.readFileSync(filename)).digest('hex');
|
|
44
|
+
function hashes() {
|
|
45
|
+
const result = {};
|
|
46
|
+
const walk = relative => {
|
|
47
|
+
const filename = path.join(repo, relative);
|
|
48
|
+
if (!fs.existsSync(filename)) return;
|
|
49
|
+
if (fs.statSync(filename).isDirectory()) for (const name of fs.readdirSync(filename).sort()) walk(path.join(relative, name));
|
|
50
|
+
else result[relative] = sha256(filename);
|
|
51
|
+
};
|
|
52
|
+
for (const name of ['bin', 'lib', 'scripts', 'package.json', 'package-lock.json']) walk(name);
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
const receipt = {
|
|
56
|
+
schemaVersion: 1, startedAt: new Date().toISOString(), node: process.version, platform: process.platform,
|
|
57
|
+
sourceRoot: repo, sourceFiles: hashes(), checks: [], success: false,
|
|
58
|
+
scope: 'Local npm archive and disposable installation; simulated providers; no model, publication or employee-device acceptance'
|
|
59
|
+
};
|
|
60
|
+
function run(command, parameters, name, settings = {}) {
|
|
61
|
+
const result = spawnSync(command, parameters, { cwd: repo, env, encoding: 'utf8', timeout: 300000, maxBuffer: 8 * 1024 * 1024, ...settings });
|
|
62
|
+
fs.writeFileSync(path.join(dir, name + '.log'), (result.stdout || '') + (result.stderr || ''));
|
|
63
|
+
if (result.error) throw result.error;
|
|
64
|
+
if (result.status !== 0) throw new Error(name + ' failed (see ' + name + '.log)');
|
|
65
|
+
return result.stdout;
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
// Invoking npm's JS entry with this Node keeps the pack/install engine at 24+.
|
|
69
|
+
const npmEntry = process.env.npm_execpath;
|
|
70
|
+
const npm = parameters => npmEntry && fs.existsSync(npmEntry)
|
|
71
|
+
? { command: process.execPath, parameters: [npmEntry, ...parameters] }
|
|
72
|
+
: { command: 'npm', parameters };
|
|
73
|
+
const pack = npm(['pack', '--ignore-scripts', '--json', '--pack-destination', dir]);
|
|
74
|
+
const metadata = JSON.parse(run(pack.command, pack.parameters, 'pack'))[0];
|
|
75
|
+
const archive = path.join(dir, metadata.filename);
|
|
76
|
+
receipt.package = { name: metadata.name, version: metadata.version, archive, sha256: sha256(archive), files: metadata.files.length };
|
|
77
|
+
const install = npm(['install', '--prefix', prefix, '--omit=dev', '--no-audit', '--no-fund', '--package-lock=false', '--fetch-retries=1', '--fetch-timeout=120000', archive]);
|
|
78
|
+
run(install.command, install.parameters, 'install');
|
|
79
|
+
const installed = path.join(prefix, 'node_modules', '@logicseek', 'hello-cc');
|
|
80
|
+
assert.equal(JSON.parse(fs.readFileSync(path.join(installed, 'package.json'), 'utf8')).version, metadata.version);
|
|
81
|
+
const publicCli = path.join(prefix, 'node_modules', '.bin', 'hcc');
|
|
82
|
+
assert.equal(fs.realpathSync(publicCli), path.join(installed, 'bin', 'hcc.mjs'));
|
|
83
|
+
const help = run(publicCli, ['--help'], 'public-cli', { cwd: prefix });
|
|
84
|
+
assert.match(help, /hello-cc|hcc/);
|
|
85
|
+
receipt.checks.push('npm pack archive installed and public hcc CLI works');
|
|
86
|
+
|
|
87
|
+
const specification = process.env.HCC_ACCEPTANCE_PLAYWRIGHT;
|
|
88
|
+
const playwrightUrl = specification && path.isAbsolute(specification) ? pathToFileURL(specification).href : specification || import.meta.resolve('playwright');
|
|
89
|
+
const { chromium } = await import(playwrightUrl);
|
|
90
|
+
const browserOutput = path.join(dir, 'browser');
|
|
91
|
+
const browserEnv = { ...env, HCC_ACCEPTANCE_PACKAGE_ROOT: installed, HCC_ACCEPTANCE_PLAYWRIGHT: playwrightUrl,
|
|
92
|
+
HCC_ACCEPTANCE_CHROME: process.env.HCC_ACCEPTANCE_CHROME || chromium.executablePath(),
|
|
93
|
+
...(process.env.HCC_ACCEPTANCE_TMUX ? { HCC_ACCEPTANCE_TMUX: process.env.HCC_ACCEPTANCE_TMUX } : {}) };
|
|
94
|
+
run(process.execPath, [path.join(installed, 'scripts', 'web-workbench-acceptance.mjs'), '--output-dir', browserOutput], 'installed-browser', { env: browserEnv, timeout: 300000 });
|
|
95
|
+
const browserReceipt = JSON.parse(fs.readFileSync(path.join(browserOutput, 'evidence.json'), 'utf8'));
|
|
96
|
+
assert.equal(browserReceipt.success, true);
|
|
97
|
+
assert.equal(browserReceipt.packageRoot, installed);
|
|
98
|
+
assert.ok(browserReceipt.assets.length >= 4 && browserReceipt.assets.every(asset => asset.bytes > 0 && asset.sha256));
|
|
99
|
+
for (const required of ['/assets/web/browser/core.mjs', '/assets/web/browser/session-sync.mjs', '/assets/web/ui-native.mjs', '/assets/web/ui-files.mjs']) {
|
|
100
|
+
assert.ok(browserReceipt.assets.some(asset => asset.path === required), 'Installed ESM asset missing: ' + required);
|
|
101
|
+
}
|
|
102
|
+
assert.equal(browserReceipt.filePreview?.success, true, 'Installed archive must complete project file preview acceptance');
|
|
103
|
+
assert.deepEqual(browserReceipt.filePreview.checks, FILE_PREVIEW_CHECKS);
|
|
104
|
+
receipt.browserReceipt = path.join(browserOutput, 'evidence.json');
|
|
105
|
+
receipt.assets = browserReceipt.assets;
|
|
106
|
+
receipt.filePreview = browserReceipt.filePreview;
|
|
107
|
+
receipt.checks.push('installed script loads static assets and completes real-browser acceptance');
|
|
108
|
+
receipt.checks.push('installed archive previews test-owned artifacts and passes read-only lifecycle checks');
|
|
109
|
+
receipt.success = true;
|
|
110
|
+
} catch (error) {
|
|
111
|
+
receipt.failure = { message: error.message, stack: error.stack }; console.error(error);
|
|
112
|
+
} finally {
|
|
113
|
+
const after = hashes();
|
|
114
|
+
receipt.sourceChanges = [...new Set([...Object.keys(receipt.sourceFiles), ...Object.keys(after)])].filter(name => receipt.sourceFiles[name] !== after[name]);
|
|
115
|
+
if (receipt.sourceChanges.length) { receipt.success = false; receipt.failure ||= { message: 'Source changed during pack/install acceptance' }; }
|
|
116
|
+
try { fs.rmSync(sandbox, { recursive: true, force: true }); receipt.cleanup = true; }
|
|
117
|
+
catch (error) { receipt.cleanup = error.message; receipt.success = false; }
|
|
118
|
+
receipt.finishedAt = new Date().toISOString();
|
|
119
|
+
fs.mkdirSync(path.dirname(output), { recursive: true }); fs.writeFileSync(output, JSON.stringify(receipt, null, 2) + '\n');
|
|
120
|
+
console.log('EVIDENCE ' + output);
|
|
121
|
+
if (!receipt.success) process.exitCode = 1;
|
|
122
|
+
}
|